0

クラスは、__ str__メソッドを介して文字列として機能することも、__call__メソッドを介して関数として機能することもできます。たとえば、リストまたはタプルとして機能できますか?

class A (object):
    def __???__ (self):
        return (1, 2, 3)

>>> a = A()
>>> a * 3
(1, 2, 3, 1, 2, 3, 1, 2, 3)

編集...

上記を明確にするためのより良い例を次に示します。

class Vector (object):
    def __init__ (self):
        self.vec = (1,2,3)
    def __???__ (self):
        # something like __repr__; non-string
        return self.vec

class Widget (object):
    def __init__ (self):
        self.vector = Vector()

>>> w = Widget()
>>> w.vector
(1, 2, 3) # not a string representation (at least, before being repr'd here)

基本的に、文字列を返さないが、Vectorインスタンスを指す名前を呼び出すだけでタプル(またはリスト)を返す__repr__のようなものが必要ですが、インスタンス、他のプロパティやメソッドへのアクセスのように。w.vector.vecまた、データを取得するために使用する必要はありません。ベクトルをwのタプル属性のように機能させながら、のようなことを実行しw.vector.whatever()たり、__​​ mul__をオーバーライドしたりして、を介してベクトルをスケーリングできるようにしますw.vector * 5。可能?

4

3 に答える 3

3

目標に応じて、listまたはtuple:のような組み込みクラスから継承するクラスを作成できます。

>>> class A(tuple):
...     def speak(self):
...         print "Bark!"
... 
>>> a = A((1,2,3)) # extra parens needed to distinguish single tuple arg from 3 scalar args
>>> a * 3
(1, 2, 3, 1, 2, 3, 1, 2, 3)
>>> a.speak()
Bark!

Vectorのユースケースを考えると、タプルをサブクラス化することでうまくいく可能性があります。

import math

class Vector(tuple):
    def magnitude(self):
        return math.sqrt( self[0]*self[0]+self[1]*self[1]+self[2]*self[2] )
于 2012-05-03T02:01:06.303 に答える
2

あなたの例の特定の振る舞い(A*3のデータの3つの連結されたコピーを与える)のために、あなたは演算子Aを実装したいと思います。__mul__()

たとえば、これらは同等です。

>>> a = [1,2,3]
>>> a*3
[1, 2, 3, 1, 2, 3, 1, 2, 3]
>>> a.__mul__(3)
[1, 2, 3, 1, 2, 3, 1, 2, 3]
>>> 

より一般的には、シーケンスタイプを実装する場合は、シーケンスタイプに対して定義されたすべての操作を実装する必要があります。定義する必要があります-

  • どういうA[3]意味ですか(__getitem__()__setitem__()
  • どういうA[1:10]意味ですか(__getslice__()
  • どういうfor item in A:意味ですか(__iter__()

等々。

listsで定義されているメソッドの完全なリストは次のとおりです。

>>> pprint.pprint(dict(list.__dict__))
{'__add__': <slot wrapper '__add__' of 'list' objects>,
 '__contains__': <slot wrapper '__contains__' of 'list' objects>,
 '__delitem__': <slot wrapper '__delitem__' of 'list' objects>,
 '__delslice__': <slot wrapper '__delslice__' of 'list' objects>,
 '__doc__': "list() -> new empty list\nlist(iterable) -> new list initialized from iterable's items",
 '__eq__': <slot wrapper '__eq__' of 'list' objects>,
 '__ge__': <slot wrapper '__ge__' of 'list' objects>,
 '__getattribute__': <slot wrapper '__getattribute__' of 'list' objects>,
 '__getitem__': <method '__getitem__' of 'list' objects>,
 '__getslice__': <slot wrapper '__getslice__' of 'list' objects>,
 '__gt__': <slot wrapper '__gt__' of 'list' objects>,
 '__hash__': None,
 '__iadd__': <slot wrapper '__iadd__' of 'list' objects>,
 '__imul__': <slot wrapper '__imul__' of 'list' objects>,
 '__init__': <slot wrapper '__init__' of 'list' objects>,
 '__iter__': <slot wrapper '__iter__' of 'list' objects>,
 '__le__': <slot wrapper '__le__' of 'list' objects>,
 '__len__': <slot wrapper '__len__' of 'list' objects>,
 '__lt__': <slot wrapper '__lt__' of 'list' objects>,
 '__mul__': <slot wrapper '__mul__' of 'list' objects>,
 '__ne__': <slot wrapper '__ne__' of 'list' objects>,
 '__new__': <built-in method __new__ of type object at 0x1E1DACA8>,
 '__repr__': <slot wrapper '__repr__' of 'list' objects>,
 '__reversed__': <method '__reversed__' of 'list' objects>,
 '__rmul__': <slot wrapper '__rmul__' of 'list' objects>,
 '__setitem__': <slot wrapper '__setitem__' of 'list' objects>,
 '__setslice__': <slot wrapper '__setslice__' of 'list' objects>,
 '__sizeof__': <method '__sizeof__' of 'list' objects>,
 'append': <method 'append' of 'list' objects>,
 'count': <method 'count' of 'list' objects>,
 'extend': <method 'extend' of 'list' objects>,
 'index': <method 'index' of 'list' objects>,
 'insert': <method 'insert' of 'list' objects>,
 'pop': <method 'pop' of 'list' objects>,
 'remove': <method 'remove' of 'list' objects>,
 'reverse': <method 'reverse' of 'list' objects>,
 'sort': <method 'sort' of 'list' objects>}
于 2012-05-03T01:39:02.680 に答える
0

strを呼び出すと、クラスは文字列として機能しません。NEW文字列オブジェクトを作成して返します。基本的にstr(something)、オブジェクトを呼び出すと、これが実際に発生します。

a = str(someObject)

a = someObject.__str__()

したがって、このstr関数は基本的に次のように考えることができます。

def str(variable):
    return variable.__str__()

list()、、などtuple()を呼び出す場合も同様ですset()。あなたが求めていると思うことが正しい場合:

tuple()、、list()およびset()すべてがクラスのメソッドを呼び出す__iter__()ので、実行したいことは次のとおりです。

class MyClass(object):
    ...
    def __iter__(self):
        ...
        return myIterable
于 2012-05-03T01:36:31.640 に答える