値を返すPythonクラス

selfではなく値を返すクラスを作ろうとしています。

リストと比較した例をお見せしましょう:

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

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

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

私はリスト(または他のオブジェクト)を真似したいのです:

>>> 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` はなぜ偽なのですか?これが質問です。

すべての方にお返事できなくて申し訳ありません。皆さんから頂いた解決策は全て試しています。setitemやgetitemなどの関数を使う必要があるので、defは使えません。

質問へのコメント (9)

何が起きているのか、あなたはとても混乱しているのだと思う。

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

  • リスト)はオブジェクトです。
  • abcde'` (文字列) はオブジェクトです。
  • 1` (整数) はオブジェクトです。
  • MyClass() (インスタンス) はオブジェクトである。
  • MyClass` (クラス) もオブジェクトである。
  • list` (型--クラスに似ている)もオブジェクトである。

これらはすべてquot;values"であり、モノを指す名前ではないという意味である。(Pythonでは値はオブジェクトと異なるものではありません。

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

オブジェクトを print する (オブジェクトの文字列表現を取得する) と、そのオブジェクトの __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
>>> 

つまり、あなたが求めていること、「MyClassがインスタンス情報ではなく、list()のようなリストを返す必要がある」ということは、何の意味もなさないということです。 list()はリストのインスタンスを返します。MyClass() は MyClass のインスタンスを返します。リストのインスタンスが欲しければ、リストのインスタンスを取得すればいい。もし、これらのオブジェクトを print したり、コンソールで見たりしたときにどのように見えるかが問題なのであれば、__str__ メソッドと __repr__ メソッドを作って、あなたが表現したいようにオブジェクトを表現してください。

等式に関する新しい質問のための更新

繰り返しますが、__str____repr__printing のためだけのものであり、それ以外の方法でオブジェクトに影響を与えることはありません。2つのオブジェクトの __repr__ の値が同じだからといって、それらが等しいとは限りません!

MyClass() != MyClass()なぜなら、あなたのクラスはこれらがどのように等しくなるかを定義していないので、(オブジェクト`型の)デフォルトの動作、つまりオブジェクトはそれ自身と等しいという動作に戻ってしまうからです:

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

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

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

>>> 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 におけるマジックメソッドの使い方](https://rszalski.github.io/magicmethods/) を見てください。 2.2. list をサブクラス化しない理由を説明してください。サブクラス化が適切でない場合は、代わりにラップされたリストのインスタンスに委譲することができます:

    class MyClass(object):
        def __init__(self):
            self._list = []
        def __getattr__(self, name):
            return getattr(self._list, name)

        # メソッドは自動的に作成される。
        # メソッドは自動的に作成される。
        もしこれらを委譲したいのであれば、 # 明示的にそうしなければならない。
        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])
解説 (3)
ソリューション

もし、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])

EDIT: オブジェクトを比較するという意味ですね。そのためには __cmp__ メソッドをオーバーライドします。

class MyClass():
    def __cmp__(self, other):
        return cmp(self.get_list(), other.get_list())
解説 (3)

__new__を使用して、クラスから値を返します。

他の人が __repr____str__、または __init__(どういうわけか)でさえあなたが望むものをあなたに与えることができることを示唆しているように、しかし、 __new__は実際のオブジェクトを返すことを望んでいるので、あなたの目的のために意味的に良い解決策になりますそれの文字列表現だけではありません。

__str ____repr__への洞察については、この回答を読んでください。 https://stackoverflow.com/a/19331543/4985585

class MyClass():
    def __new__(cls):
        return list() #or anything you want

>>> MyClass()
[]   #Returns a true list not a repr or string
解説 (2)
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']
解説 (1)

あなたが記述しているのは、クラスではなく関数である。

def Myclass():
    return []
解説 (3)