214

いくつかの属性とメソッドを持つ python オブジェクトがあります。オブジェクトの属性を反復処理したい。

class my_python_obj(object):
    attr1='a'
    attr2='b'
    attr3='c'

    def method1(self, etc, etc):
        #Statements

すべてのオブジェクト属性とその現在の値を含むディクショナリを生成したいのですが、それを動的な方法で行いたいです (したがって、後で別の属性を追加する場合、関数も更新することを覚えておく必要はありません)。

PHP では変数をキーとして使用できますが、Python のオブジェクトは添え字を付けることができず、これにドット表記を使用すると、var の名前で新しい属性が作成されますが、これは私の意図ではありません。

物事を明確にするために:

def to_dict(self):
    '''this is what I already have'''
    d={}
    d["attr1"]= self.attr1
    d["attr2"]= self.attr2
    d["attr3"]= self.attr3
    return d

·

def to_dict(self):
    '''this is what I want to do'''
    d={}
    for v in my_python_obj.attributes:
        d[v] = self.v
    return d

更新: 属性とは、メソッドではなく、このオブジェクトの変数のみを意味します。

4

8 に答える 8

300

次のようなクラスがあると仮定します

>>> class Cls(object):
...     foo = 1
...     bar = 'hello'
...     def func(self):
...         return 'call me'
...
>>> obj = Cls()

オブジェクトを呼び出すdirと、Python の特別な属性を含む、そのオブジェクトのすべての属性が返されます。メソッドなど、一部のオブジェクト属性は呼び出し可能ですが。

>>> dir(obj)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'bar', 'foo', 'func']

リスト内包表記を使用して、いつでも特別なメソッドを除外できます。

>>> [a for a in dir(obj) if not a.startswith('__')]
['bar', 'foo', 'func']

または、マップ/フィルターを好む場合。

>>> filter(lambda a: not a.startswith('__'), dir(obj))
['bar', 'foo', 'func']

メソッドを除外したい場合は、ビルトインcallableをチェックとして使用できます。

>>> [a for a in dir(obj) if not a.startswith('__') and not callable(getattr(obj, a))]
['bar', 'foo']

を使用して、クラスとそのインスタンス オブジェクトの違いを調べることもできます。

>>> set(dir(Cls)) - set(dir(object))
set(['__module__', 'bar', 'func', '__dict__', 'foo', '__weakref__'])
于 2012-07-24T18:54:44.790 に答える
4

Pythonのオブジェクトは、属性(関数を含む)をと呼ばれるdictに格納し__dict__ます。これを使用して属性に直接アクセスできます(ただし、通常は使用しないでください)。リストだけが必要な場合は、を呼び出すこともできますdir(obj)。これは、すべての属性名を含む反復可能オブジェクトを返し、それをに渡すことができますgetattr

ただし、変数の名前で何かをする必要があるのは、通常、悪い設計です。それらをコレクションに入れてみませんか?

class Foo(object):
    def __init__(self, **values):
        self.special_values = values

次に、次のコマンドでキーを反復処理できます。for key in obj.special_values:

于 2012-07-24T18:56:16.607 に答える
2
class SomeClass:
    x = 1
    y = 2
    z = 3
    
    def __init__(self):
        self.current_idx = 0
        self.items = ["x", "y", "z"]
            
    def next(self):
        if self.current_idx < len(self.items):
            self.current_idx += 1
            k = self.items[self.current_idx-1]
            return (k, getattr(self, k))
        else:
            raise StopIteration
            
    def __iter__(self):
        return self

次に、それをイテラブルとして呼び出します

s = SomeClass()
for k, v in s:
    print k, "=", v
于 2012-07-24T19:05:21.833 に答える
0

これに対する正解は、すべきではないということです。このタイプのものが必要な場合は、dictを使用するか、コンテナに属性を明示的に追加する必要があります。デコレータについて学ぶことで、それを自動化できます。

特に、ちなみに、あなたの例のmethod1は、同じように優れた属性です。

于 2012-07-24T18:55:52.190 に答える
-1

Python 3.6 の場合

class SomeClass:

    def attr_list(self, should_print=False):

        items = self.__dict__.items()
        if should_print:
            [print(f"attribute: {k}    value: {v}") for k, v in items]

        return items
于 2018-03-09T16:23:39.407 に答える