2013-04-09 22 views
6

我想查看object .__ new __()的源代碼定義,並決定使用這種快速方式訪問該代碼。爲什麼Python給我一個TypeError (is not a type:method),當type()告訴我這是一個類型:方法?如何動態實例化(通過類名作爲字符串)在本例中調用getThings()的類?

(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'> 
>>> 

我想看看在首位的定義的原因是因爲我想調用的方法需要一個特定的類作爲其第一個參數的一個實例。

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

還值得一提的是,FunClass是SadClass的子類,並作爲錯誤信息所暗示的,我已經有SadClass的一個實例。我覺得我有一切我需要撥打getThings(),但我想知道是否有一個聰明的方法來獲得FunClass的實例,我可以稱其爲getThings()

我只想聲明一個我需要的實例,但我遇到了麻煩,因爲最終被調用的類和函數是基於用戶方法輸入參數(字符串),我使用getattr()來獲得類對象(FunClass)和方法對象(getThings)。我創造FunClass的一個實例,試圖在這裏結束了:

(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 
>>> 

最終,我只是想能夠調用getThings,我想需要FunClass的一個實例。我也有一個變量ClassMethod,我嘗試用它來調用該方法。同樣,我的類名和方法名來作爲字符串,我使用的getattr()申報的對象,像這樣:

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

當我打電話ClassMethod(),我得到中看到的錯誤(4)。我可能有不止一個問題,但對任何方面的洞察力都會很棒!謝謝。

編輯:

(按照@nneonneo的答案)

我落得這樣做:

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

其中 「FunClass」 和 「getThing」 實際上是傳遞給函數的字符串,並且可以是任何數量的類/方法組合。 Thing1和Thing2需要在其他地方實例化父類(SadClass),所以這允許我使用這些現有屬性實例化其子類「FunClass」,然後調用FunClass的類方法之一。 SadClass具有__init__,FunClass不具有。問題解決了。

回答

5

爲什麼直接打電話給__new__?只需創建一個像這樣的新實例:

obj = FunClass() 

或者使用動態名稱globals()['FunClass']()

然後,你可以做

obj.getThings() 

,或者動態,getattr(obj, 'getThings')()

順便說一句,你看不到object.__new__的來源,因爲它是一個內置的方法(所以它在較低的層次上實現,例如C for CPython)。

+0

全局()的想法工作!謝謝。它允許我使用動態類名,這正是我所需要的。 – samstav 2013-04-09 16:22:15

2

如果你真的需要直接調用__new__出於某種原因,而不是僅僅調用每nneonneo的答案類,你要明白,__new__ - 無論出於何種原因 - 實際上不是一個classmethod,即使它有一個你的簽名,並需要在類明確傳遞:

inst = ClassObject.__new__(ClassObject) 

應該工作。但不要忘記,致電班級本身並不止於此 - 你可能想通過調用inst.__init__()做其餘的工作。

+0

很高興知道,re:明確地通過班級。如果可以的話,我會投票。謝謝 – samstav 2013-04-09 16:29:17