2016-11-12 14 views
1

したがって、私が作成するクラスに対してtype()関数の動作を変更したいとします。私は私が何を意味するかを証明するために、2つのクラス、1「古いスタイル」クラスとobjectから継承する1「新しいスタイル」を、作成します:ユーザー作成クラスのtype()関数の動作を変更する

class Foo: 
    pass 

class Bar(object): 
    pass 

今、私はそれらのそれぞれのインスタンスを作成します:

spam = Foo() 
eggs = Bar() 

これらの各クラスでtype()機能を使用するとどうなりますか?

>>> type(spam) 
<type 'instance'> 
>>> type(eggs) 
<class '__main__.Bar'> 

私はそれがよりこのように表示されるように、この動作を変更する方法を探しています:

>>> type(spam) 
<type 'foo'> 

私は他の多くのオブジェクトを見てきましたが、デフォルトのデータ型以外にも(これを行います明らかに)。例:

このようなものはかなり近いですが、私が助けることができれば、メンバーシップドットを中央に持たない方がよいでしょう。 (はい、私はこれでを使用していたコードは、インポートしたファイルになります。)

>>> from itertools import * 
>>> z = imap(pow, (2, 3, 4), (5, 2, 4)) 
>>> type(z) 
<type 'itertools.imap'> 

私はこの質問への答えは本当に簡単であると確信しているが、何らかの理由で、私はどのように言葉に把握することはできませんこれに関する検索クエリ。どんな助けもありがとう。

答えて

0

typeが呼び出されたときに返すものは、オブジェクトのクラスです。表示されている文字列は、その "表現"であり、クラスのreprの呼び出しによって生成されます。それ自身 - reprが対話型プロンプトによって呼び出されます。 Pythonオブジェクトは__repr__メソッドを定義することによって表現をカスタマイズします。

クラスの__repr__をカスタマイズする必要があり、そのインスタンスではないため、クラスのクラス自体のメソッドをオーバーライドする必要があります。 Pythonではmetaclassと呼ばれています。

すべてのPython "新しいスタイル"オブジェクトのベースメタクラスはtypeです。 typeは、オブジェクトのクラスを返す単純な関数よりもはるかに優れています。実際にはそのことです。すべての「ベースメタクラス」です。 (古いスタイルのクラスには別のメタクラスがありますが、の場合は、には古いスタイルのクラスを使用しないでください。まったく真剣です。実際には、今のところPython 3を使用する必要があります。

したがって、クラスのクラスをカスタマイズするには、typeから継承する新しいクラスを作成します。あなたはそれを行う方法を説明し、__new__、または__init__を上書きするいくつかのブログ投稿とドキュメントを見つけるでしょう。しかし、この場合、 は、クラスクリティカルの実際の動作を変更する必要はありません。

あなたはただ行うことができます。

class MyType(type): 
    def __repr__(cls): 
     return "<type '{}'>".format (cls.__name__) 

class Foo(object): 
    __metaclass__ = MyType 

そして、あなたが望むようには動作します。私がメタクラス '__repr__の引数をselfの代わりにclsとしていることに注意してください。それは意味論的目的のためにjsutです。インスタンス自体はインスタンスになりますが、インスタンスはクラスです。 「自己」が使われていればうまくいくでしょう。

最後に、デフォルトでreprのインスタンスがどのように変更されているかが変更され、その表現が醜いことがあります。あなたがそれを嫌うならば、あなたのクラスのためだけに(メタクラス用ではなく)__repr__メソッドを書いて、その表現を文字列形式にする方法をさらにカスタマイズしてください。

+0

詳細な対応をありがとうございます!うん、私はすでに '__repr__'関数がクラスそのものになっています。あなたが 'type(type(Foo()))'を実行すると、 ' __main __。MyType '>'を得ることができます。通常は 'type(type(something))'は ''を返します。これを修正して 'Foo'クラスを他のデータ型と完全に一致させる方法はありますか?ありがとう。 –

関連する問題