Pab*_*her 137 python oop iteration attributes
我有一个python对象,有几个属性和方法.我想迭代对象属性.
class my_python_obj(object):
attr1='a'
attr2='b'
attr3='c'
def method1(self, etc, etc):
#Statements
Run Code Online (Sandbox Code Playgroud)
我想生成一个包含所有对象属性及其当前值的字典,但我想以动态的方式进行(所以如果以后我添加另一个属性,我也不必记得更新我的函数).
在PHP中,变量可以用作键,但是python中的对象是不可编写的,如果我使用点符号,它会创建一个名为my 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
Run Code Online (Sandbox Code Playgroud)
·
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
Run Code Online (Sandbox Code Playgroud)
更新:使用属性我只是指这个对象的变量,而不是方法.
Mei*_*ham 204
假设你有一个类如
>>> class Cls(object):
... foo = 1
... bar = 'hello'
... def func(self):
... return 'call me'
...
>>> obj = Cls()
Run Code Online (Sandbox Code Playgroud)
调用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']
Run Code Online (Sandbox Code Playgroud)
您始终可以使用列表推导过滤掉特殊方法.
>>> [a for a in dir(obj) if not a.startswith('__')]
['bar', 'foo', 'func']
Run Code Online (Sandbox Code Playgroud)
或者如果你喜欢地图/过滤器.
>>> filter(lambda a: not a.startswith('__'), dir(obj))
['bar', 'foo', 'func']
Run Code Online (Sandbox Code Playgroud)
如果要过滤掉方法,可以使用内置callable检查作为检查.
>>> [a for a in dir(obj) if not a.startswith('__') and not callable(getattr(obj, a))]
['bar', 'foo']
Run Code Online (Sandbox Code Playgroud)
您还可以使用检查您的类与其父级之间的差异.
>>> set(dir(Cls)) - set(dir(object))
set(['__module__', 'bar', 'func', '__dict__', 'foo', '__weakref__'])
Run Code Online (Sandbox Code Playgroud)
Sma*_*ron 47
通常__iter__在你的类中放置一个方法并遍历对象属性或将这个mixin类放在你的类中.
class IterMixin(object):
def __iter__(self):
for attr, value in self.__dict__.iteritems():
yield attr, value
Run Code Online (Sandbox Code Playgroud)
你的班:
>>> 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'}
Run Code Online (Sandbox Code Playgroud)
Nat*_*han 45
正如一些答案/评论中已经提到的,Python 对象已经存储了它们的属性字典(不包括方法)。这可以作为 访问__dict__,但更好的方法是使用vars(尽管输出是相同的)。请注意,修改此字典将修改实例上的属性!这可能很有用,但也意味着您应该小心使用这本词典。这是一个快速示例:
class A():
def __init__(self, x=3, y=2, z=5):
self.x = x
self._y = y
self.__z__ = z
def f(self):
pass
a = A()
print(vars(a))
# {'x': 3, '_y': 2, '__z__': 5}
# all of the attributes of `a` but no methods!
# note how the dictionary is always up-to-date
a.x = 10
print(vars(a))
# {'x': 10, '_y': 2, '__z__': 5}
# modifying the dictionary modifies the instance attribute
vars(a)["_y"] = 20
print(vars(a))
# {'x': 10, '_y': 20, '__z__': 5}
Run Code Online (Sandbox Code Playgroud)
使用dir(a)这种方法来解决这个问题是一种奇怪的,如果不是完全坏的方法。如果您真的需要遍历类的所有属性和方法(包括像 之类的特殊方法__init__),那就太好了。但是,这似乎不是您想要的,甚至通过应用一些脆弱的过滤来尝试删除方法并仅保留属性,即使已接受的答案也很糟糕;您可以看到A上面定义的类将如何失败。
(使用__dict__已经在几个答案中完成,但它们都定义了不必要的方法而不是直接使用它。只有评论建议使用vars)。
| 归档时间: |
|
| 查看次数: |
126247 次 |
| 最近记录: |