29

自己ではなく、値を返すクラスを作成しようとしています。

リストと比較する例を示します。

>>> l = list()
>>> print(l)
[]
>>> class MyClass:
>>>     pass

>>> mc = MyClass()
>>> print mc
<__main__.MyClass instance at 0x02892508>

list()インスタンス情報ではなく、MyClass がリストを返すようにする必要があります。リストのサブクラスを作成できることを知っています。しかし、サブクラス化せずにそれを行う方法はありますか?

リスト (または他のオブジェクト) を模倣したい:

>>> l1 = list()
>>> l2 = list()
>>> l1
[]
>>> l2
[]
>>> l1 == l2
True
>>> class MyClass():
def __repr__(self):
    return '[]'


>>> m1 = MyClass()
>>> m2 = MyClass()
>>> m1
[]
>>> m2
[]
>>> m1 == m2
False

なぜm1 == m2偽なのですか?これが質問です。

全員に返信できなくてすみません。私はあなたが私に与えるすべての解決策を試しています。defsetitem、getitem などの関数を使用する必要があるため、使用できません。

4

6 に答える 6

45

何が起こっているのか、あなたはとても混乱していると思います。

Python では、すべてがオブジェクトです。

  • [](リスト) はオブジェクトです
  • 'abcde'(文字列) はオブジェクトです
  • 1(整数) はオブジェクトです
  • MyClass()(インスタンス) はオブジェクトです
  • MyClass(クラス)もオブジェクトです
  • list(型 -- クラスによく似ています) もオブジェクトです

それらはすべて、物であり、物を指す名前ではないという意味で「値」です。(変数は値を参照する名前です。) 値は、Python のオブジェクトと何ら変わりはありません。

MyClass()クラス オブジェクト (や など)を呼び出すと、list()そのクラスのインスタンスが返されます。(list実際にはクラスではなく型ですが、ここでは少し単純化しています。)

オブジェクトを出力する (つまり、オブジェクトの文字列表現を取得する) と、そのオブジェクトの__str__または__repr__マジック メソッドが呼び出され、戻り値が出力されます。

例えば:

>>> class MyClass(object):
...     def __str__(self):
...             return "MyClass([])"
...     def __repr__(self):
...             return "I am an instance of MyClass at address "+hex(id(self))
... 
>>> m = MyClass()
>>> print m
MyClass([])
>>> m
I am an instance of MyClass at address 0x108ed5a10
>>> 

したがって、「インスタンス情報ではなく、list() のようなリストを MyClass が返す必要がある」という要求は意味がありません。 list()リストインスタンスを返します。MyClass()MyClass インスタンスを返します。リスト インスタンスが必要な場合は、リスト インスタンスを取得します。代わりに、これらのオブジェクトを使用したり、コンソールで見たりしたときにどのように見えるかがprint問題である場合は、それらを表現したいように表現する__str__andメソッドを作成します。__repr__

平等に関する新しい質問の更新

繰り返しますが、これは印刷専用で__str__あり、それ以外の方法でオブジェクトに影響を与えることはありません。2 つのオブジェクトが同じ値を持っているからといって、それらが等しいとは限りません。__repr____repr__

MyClass() != MyClass()クラスはこれらがどのように等しいかを定義していないため、(object型の) デフォルトの動作にフォールバックします。つまり、オブジェクトはそれ自体とのみ等しいということです。

>>> m = MyClass()
>>> m1 = m
>>> m2 = m
>>> m1 == m2
True
>>> m3 = MyClass()
>>> m1 == m3
False

これを変更したい場合は、比較マジックメソッドのいずれかを使用してください

たとえば、すべてに等しいオブジェクトを持つことができます。

>>> class MyClass(object):
...     def __eq__(self, other):
...             return True
... 
>>> m1 = MyClass()
>>> m2 = MyClass()
>>> m1 == m2
True
>>> m1 == m1
True
>>> m1 == 1
True
>>> m1 == None
True
>>> m1 == []
True

次の 2 つのことを行う必要があると思います。

  1. Python でのマジック メソッドの使用に関するこのガイドをご覧ください。
  2. list必要なものが非常にリストに似ている場合は、サブクラス化しない理由を正当化してください。サブクラス化が適切でない場合は、代わりにラップされたリスト インスタンスに委譲できます。

    class MyClass(object):
        def __init__(self):
            self._list = []
        def __getattr__(self, name):
            return getattr(self._list, name)
    
        # __repr__ and __str__ methods are automatically created
        # for every class, so if we want to delegate these we must
        # do so explicitly
        def __repr__(self):
            return "MyClass(%s)" % repr(self._list)
        def __str__(self):
            return "MyClass(%s)" % str(self._list)
    

    これは、リストでなくても (つまり、サブクラス化せずにlist) リストのように振る舞うようになりました。

    >>> c = MyClass()
    >>> c.append(1)
    >>> c
    MyClass([1])
    
于 2012-09-13T19:08:15.507 に答える
40

サブクラス化せずにクラスを一種のリストに変換する方法が必要な場合は、リストlistを返すメソッドを作成するだけです。

def MyClass():
    def __init__(self):
        self.value1 = 1
        self.value2 = 2

    def get_list(self):
        return [self.value1, self.value2...]


>>>print MyClass().get_list()
[1, 2...]

リストを出力するつもりならprint MyClass()、オーバーライドして__repr__ください:

class MyClass():        
    def __init__(self):
        self.value1 = 1
        self.value2 = 2

    def __repr__(self):
        return repr([self.value1, self.value2])

編集:オブジェクトを比較する方法を意味していたようです。そのためには、__cmp__メソッドをオーバーライドします。

class MyClass():
    def __cmp__(self, other):
        return cmp(self.get_list(), other.get_list())
于 2012-09-13T18:49:31.420 に答える
9
class MyClass():
    def __init__(self, a, b):
        self.value1 = a
        self.value2 = b

    def __call__(self):
        return [self.value1, self.value2]

テスト:

>>> x = MyClass('foo','bar')
>>> x()
['foo', 'bar']
于 2013-10-26T02:23:26.977 に答える
4

クラスではなく関数を記述しています。

def Myclass():
    return []
于 2012-09-13T18:31:26.697 に答える