2013-04-09 21 views
6

object .__ new __() için kaynak tanımını görmek istiyorum ve bu kod için bu hızlı yolu kullanmaya karar verdim. Neden python banaveriyor? type() bana bunun bir tür olduğunu söylüyor: yöntem? Aramaya çalışıyorum yöntem ilk argüman olarak belirli bir sınıfının bir örneğini gerektirdiğindenBu örnekte getThings() işlevini çağırmak için sınıfı dinamik olarak (dize olarak sınıf adı olarak) nasıl yapabilirim?

(1) 
>>> import inspect 
>>> print inspect.getsource(object.__new__) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/inspect.py", line 701, in getsource 
    lines, lnum = getsourcelines(object) 
    File "/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/inspect.py", line 690, in getsourcelines 
    lines, lnum = findsource(object) 
    File "/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/inspect.py", line 526, in findsource 
    file = getfile(object) 
    File "/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/inspect.py", line 420, in getfile 
    'function, traceback, frame, or code object'.format(object)) 
TypeError: <built-in method __new__ of type object at 0x10a2d9410> is not a module, class, method, function, traceback, frame, or code object 

>>> type(object.__new__) 
<type 'builtin_function_or_method'> 
>>> 

ben ilk etapta tanımını görmek istedim nedenidir.

(2) 
TypeError: unbound method getThings() must be called with FunClass instance as first argument (got SadClass instance instead) 

Ayrıca FunClass SadClass bir alt sınıfıdır ve hata mesajı da anlaşılacağı gibi, zaten SadClass bir örneğini olması dikkati çekiyor. Ben getThings() aramak için gereken her şey var gibi hissediyorum, ama ben getThings() arayabilir hangi ile hangi FunClass örneği almak için akıllı bir yolu var mı?

İhtiyacım olan şeylerin bir örneğini bildirmek isterim, ancak sorun yaşıyorum çünkü çağrılan sınıf ve işlev, bir sınıf almak için getattr() kullandığım kullanıcı yöntemi girdisi argümanlarına (dizeler) dayanıyor nesne (FunClass) ve bir yöntem nesnesi (getThings). FunClass bir örneğini oluşturarak benim girişimleri burada bitti:

(3) 
>>> ClassObject = getattr(FunClass,"FunClass") 
>>> ClassObject 
<class 'FunClass.FunClass'> 
>>> ClassObject.__new__() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: object.__new__(): not enough arguments 
>>> 

Sonuçta, ben sadece FunClass örneğini gerektirir varsayalım halletmek, arama yapabilmek istiyorum. Ayrıca, yöntemi çağırmak için kullanmaya çalıştığım bir ClassMethod değişkenim de var. Yine, benim sınıf adı ve yöntem adı dizeleri olarak gelir ve bu gibi nesneleri beyan etmek getattr() kullanıyordum: Ben ClassMethod() çağırdığınızda

(4) 
>>> ClassMethod = getattr(FunClass, "getThings") 
>>> ClassMethod 
<unbound method FunClass.getThings> 

, ben de görüldüğü hata alıyorum (4). Birden fazla sorunum olabilir, ancak herhangi bir yönüyle ilgili fikir harika olurdu! Teşekkürler.

DÜZENLEME:

yaptığım sona erdi

(@nneonneo 'ın cevabı uyarınca): "FunClass" ve "getThing" aslında işlevi geçirilen dizeleri

ClassInstance = globals()["FunClass"](self.thing1, self.thing2) 
ClassMethod = getattr(ClassInstance, "getThing") 
ClassMethod() # to call the function 

ve herhangi bir sayıda sınıf/yöntem kombinasyonu olabilir. Thing1 ve Thing2, ana sınıfı (SadClass) başka bir yerde oluşturmak için gereklidir, bu yüzden bu varolan öznitelikleri kullanarak "FunClass" alt sınıfını oluşturmamı ve ardından FunClass'ın sınıf yöntemlerinden birini çağırmamı sağlar. SadClass __init__ ve FunClass'a sahip değil. Sorun çözüldü.

cevap

5

Neden doğrudan __new__ numaralı telefonu arıyorsun?

obj = FunClass() 

ya, globals()['FunClass']() dinamik adı kullanmak: Sadece bu gibi yeni bir örneğini yapmak.

Sonra sadece dinamik

obj.getThings() 

ya, getattr(obj, 'getThings')() yapabilirsiniz. Bu arada, yerleşik bir yöntem (ve daha düşük bir düzeyde, örneğin CPython için C) uygulandığı için object.__new__ kaynağını göremezsiniz.

+0

Globals() fikri işe yaradı! Teşekkürler. Tam olarak ihtiyacım olan dinamik bir sınıf adı kullanmama izin veriyor. – samstav

2

Eğer gerçekten sadece nneonneo en Yanıt başına sınıfını aramak yerine, nedense doğrudan __new__ aramaya gerek sen __new__ anlamak gerekiyorsa - bu olsa bile, aslında bir classmethod değil - Sebebi ne olursa olsun Birinin imzası ve sınıfta açıkça geçmeniz gereken:

çalışmalıdır. Ama unutmayın ki, sınıfın kendisini aramaz, muhtemelen, inst.__init__() numaralı telefonu arayarak işin geri kalanını da yapmak istersiniz.

+0

Bilmekte fayda var, yeniden: sınıfta açıkça geçirin. Yapabilirsem oy kullanırdım. Teşekkürler – samstav

İlgili konular