2013-04-09 5 views
6

オブジェクト.__ new __()のソース定義を見たいと思っていて、このコードに簡単にアクセスすることに決めました。なぜ私はを与えているのですか?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 
>>> 

最終的に、私はちょうど私がFunClassのインスタンスを必要としgetThingsを呼び出すことができるようにしたいです。私はまた、メソッドを呼び出すために使用しようとした変数ClassMethodを持っています。ここでも、私のクラス名やメソッド名は文字列としてで来て、私はこのように、オブジェクトを宣言するのgetattr()を使用していた:私はClassMethod()を呼び出すとき

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

は、私がで見られるエラーが発生します(4)。私は複数の問題を抱えているかもしれませんが、どんな面でも洞察力はすばらしいでしょう!ありがとう。

EDIT:

私がやってしまった

(@nneonneoの答えあたりとして): "FunClass" と "getThing" は、実際に関数に渡された文字列である

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

任意の数のクラス/メソッドの組み合わせとすることができる。 Thing1とThing2は他のどこかで親クラス(SadClass)をインスタンス化する必要があります。そのため、これらの既存の属性を使用してサブクラス「FunClass」をインスタンス化し、FunClassのクラスメソッドの1つを呼び出します。 SadClassには__init__があり、FunClassにはありません。問題が解決しました。

答えて

5

なぜ__new__に直接電話するのですか?

obj = FunClass() 

や、動的な名前を使用するには、globals()['FunClass']():ちょうどこのような新しいインスタンスを作成します。

次に、あなたは

obj.getThings() 

または、動的に、getattr(obj, 'getThings')()を単に行うことができます。

ところで、object.__new__のソースは表示されません。これは組み込みの方法です(したがって、CPythonではCなどの低レベルで実装されています)。

+0

globals()のアイデアは機能しました!ありがとう。動的クラス名を使うことができます。これはまさに私が必要としていたものです。 – samstav

2

あなたは本当にだけnneonneoの答えあたりのクラスを呼び出すのではなく、何らかの理由で直接__new__を呼び出す必要がある、あなたは__new__があることを理解する必要がある場合 - それは持っているにもかかわらず、実際にclassmethodではありません - 何らかの理由でその署名を明示的に渡す必要があります。

が動作するはずです。しかし、クラスそのものを呼び出すことはそこで止まらないことを忘れないでください。inst.__init__()を呼び出して、残りの作業をしたいと思っています。

+0

よく知っておきたい、re:明示的にクラスを渡す。もしできれば、私は投票するだろう。ありがとう – samstav

関連する問題