在python中遍历对象属性

时间:2022-03-18 18:12:45

I have a python object with several attributes and methods. I want to iterate over object attributes.

我有一个具有多个属性和方法的python对象。我想对对象属性进行迭代。

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

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

I want to generate a dictionary containing all of the objects attributes and their current values, but I want to do it in a dynamic way (so if later I add another attribute I don't have to remember to update my function as well).

我想生成一个包含所有对象属性和它们当前值的字典,但是我想以一种动态的方式来实现它(因此,如果以后我添加了另一个属性,我就不需要记得更新我的函数了)。

In php variables can be used as keys, but objects in python are unsuscriptable and if I use the dot notation for this it creates a new attribute with the name of my var, which is not my intent.

在php变量中可以作为键使用,但是python中的对象是unsusabletable,如果我使用点符号,它会创建一个带有我的var名称的新属性,这不是我的意图。

Just to make things clearer:

为了让事情更清楚:

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

Update: With attributes I mean only the variables of this object, not the methods.

更新:对于属性,我指的是这个对象的变量,而不是方法。

7 个解决方案

#1


146  

Assuming you have a class such as

假设您有一个类,比如。

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

calling dir on the object gives you back all the attributes of that object, including python special attributes. Although some object attributes are callable, such as methods.

调用对象上的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']

You can always filter out the special methods by using a list comprehension.

您可以通过使用列表理解来过滤特殊的方法。

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

or if you prefer map/filters.

或者你更喜欢地图/过滤器。

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

If you want to filter out the methods, you can use the builtin callable as a check.

如果想要过滤掉这些方法,可以使用builtin callable作为检查。

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

You could also inspect the difference between your class and its parent using.

您还可以检查类与其父类之间的差异。

>>> set(dir(Cls)) - set(dir(object))
set(['__module__', 'bar', 'func', '__dict__', 'foo', '__weakref__'])

#2


33  

in general put a __iter__ method in your class and iterate through the object attributes or put this mixin class in your class.

通常,在类中放置__iter__方法并遍历对象属性,或者将这个mixin类放到类中。

class IterMixin(object):
    def __iter__(self):
        for attr, value in self.__dict__.iteritems():
            yield attr, value

Your class:

你的类:

>>> class YourClass(IterMixin): pass
...
>>> yc = YourClass()
>>> yc.one = range(15)
>>> yc.two = 'test'
>>> dict(yc)
{'one': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], 'two': 'test'}

#3


3  

Objects in python store their atributes (including functions) in a dict called __dict__. You can (but generally shouldn't) use this to access the attributes directly. If you just want a list, you can also call dir(obj), which returns an iterable with all the attribute names, which you could then pass to getattr.

python中的对象将其atributes(包括函数)存储在一个名为__dict__的法令中。您可以(但通常不应该)使用它直接访问属性。如果您只想要一个列表,您还可以调用dir(obj),它返回一个具有所有属性名称的可迭代值,然后您可以将其传递给getattr。

However, needing to do anything with the names of the variables is usually bad design. Why not keep them in a collection?

但是,需要对变量名进行任何操作通常是糟糕的设计。为什么不把它们收藏起来呢?

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

You can then iterate over the keys with for key in obj.special_values:

然后可以在object .special_values中使用for键对键进行迭代:

#4


1  

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

then just call it as an iterable

然后把它称为可迭代的

s=someclass()
for k,v in s:
    print k,"=",v

#5


1  

For python 3.6

对于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

#6


0  

For python 3.6

对于python 3.6

class SomeClass:

    def attr_list1(self, should_print=False):

        for k in self.__dict__.keys():
            v = self.__dict__.__getitem__(k)
            if should_print:
                print(f"attr: {k}    value: {v}")

    def attr_list(self, should_print=False):

        b = [(k, v) for k, v in self.__dict__.items()]
        if should_print:
            [print(f"attr: {a[0]}    value: {a[1]}") for a in b]
        return b

#7


-1  

The correct answer to this is that you shouldn't. If you want this type of thing either just use a dict, or you'll need to explicitly add attributes to some container. You can automate that by learning about decorators.

正确的答案是你不应该这样做。如果您想要这种类型的东西,您可以使用一个dict类型,或者需要显式地向某个容器添加属性。通过学习decorator,您可以实现自动化。

In particular, by the way, method1 in your example is just as good of an attribute.

顺便说一下,您的示例中的method1恰好是一个属性。

#1


146  

Assuming you have a class such as

假设您有一个类,比如。

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

calling dir on the object gives you back all the attributes of that object, including python special attributes. Although some object attributes are callable, such as methods.

调用对象上的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']

You can always filter out the special methods by using a list comprehension.

您可以通过使用列表理解来过滤特殊的方法。

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

or if you prefer map/filters.

或者你更喜欢地图/过滤器。

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

If you want to filter out the methods, you can use the builtin callable as a check.

如果想要过滤掉这些方法,可以使用builtin callable作为检查。

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

You could also inspect the difference between your class and its parent using.

您还可以检查类与其父类之间的差异。

>>> set(dir(Cls)) - set(dir(object))
set(['__module__', 'bar', 'func', '__dict__', 'foo', '__weakref__'])

#2


33  

in general put a __iter__ method in your class and iterate through the object attributes or put this mixin class in your class.

通常,在类中放置__iter__方法并遍历对象属性,或者将这个mixin类放到类中。

class IterMixin(object):
    def __iter__(self):
        for attr, value in self.__dict__.iteritems():
            yield attr, value

Your class:

你的类:

>>> class YourClass(IterMixin): pass
...
>>> yc = YourClass()
>>> yc.one = range(15)
>>> yc.two = 'test'
>>> dict(yc)
{'one': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], 'two': 'test'}

#3


3  

Objects in python store their atributes (including functions) in a dict called __dict__. You can (but generally shouldn't) use this to access the attributes directly. If you just want a list, you can also call dir(obj), which returns an iterable with all the attribute names, which you could then pass to getattr.

python中的对象将其atributes(包括函数)存储在一个名为__dict__的法令中。您可以(但通常不应该)使用它直接访问属性。如果您只想要一个列表,您还可以调用dir(obj),它返回一个具有所有属性名称的可迭代值,然后您可以将其传递给getattr。

However, needing to do anything with the names of the variables is usually bad design. Why not keep them in a collection?

但是,需要对变量名进行任何操作通常是糟糕的设计。为什么不把它们收藏起来呢?

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

You can then iterate over the keys with for key in obj.special_values:

然后可以在object .special_values中使用for键对键进行迭代:

#4


1  

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

then just call it as an iterable

然后把它称为可迭代的

s=someclass()
for k,v in s:
    print k,"=",v

#5


1  

For python 3.6

对于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

#6


0  

For python 3.6

对于python 3.6

class SomeClass:

    def attr_list1(self, should_print=False):

        for k in self.__dict__.keys():
            v = self.__dict__.__getitem__(k)
            if should_print:
                print(f"attr: {k}    value: {v}")

    def attr_list(self, should_print=False):

        b = [(k, v) for k, v in self.__dict__.items()]
        if should_print:
            [print(f"attr: {a[0]}    value: {a[1]}") for a in b]
        return b

#7


-1  

The correct answer to this is that you shouldn't. If you want this type of thing either just use a dict, or you'll need to explicitly add attributes to some container. You can automate that by learning about decorators.

正确的答案是你不应该这样做。如果您想要这种类型的东西,您可以使用一个dict类型,或者需要显式地向某个容器添加属性。通过学习decorator,您可以实现自动化。

In particular, by the way, method1 in your example is just as good of an attribute.

顺便说一下,您的示例中的method1恰好是一个属性。