如何在不知道名称的情况下获取类的属性

时间:2017-08-28 12:07:06

标签: python

我有以下课程:

class TestClass(object):
def __init__(self, **kwargs):
    for key, value in kwargs.items(): #items return list of dict
        setattr(self, key, value)

示例用法:

obj = MessageItem(**{"testkey1":"tval1", "tkey2":"tval2", "tkey3":"tval3"})

如何在不知道属性名称的情况下迭代此结构? Python为我们提供了内置方法__getattribute__,但我仍然需要知道所请求属性的名称:

print(obj.__getattribute__("testkey1"))

1 个答案:

答案 0 :(得分:3)

__dict__属性可以保存您想要的内容。 上课了:

>>> class Foo:
...     def __init__(self, x):
...             self.x = x
...
>>> Foo.__dict__
mappingproxy({'__module__': '__main__', '__init__': <function Foo.__init__ at
0x000001CC1821EEA0>, '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__':
<attribute '__weakref__' of 'Foo' objects>, '__doc__': None})

任何实例都有它:

>>> f = Foo(2)
>>> f.__dict__
{'x': 2}

您应该通过vars内置函数访问此属性。 致电vars(foo)将返回foo.__dict__。 请参阅此相关帖子:Use __dict__ or vars()?

Documentation for vars

  

瓦尔([对象])

     

返回具有__dict__属性的模块,类,实例或任何其他对象的__dict__属性。

     

模块和实例等对象具有可更新的__dict__属性;但是,其他对象可能会对其进行写入限制   __dict__属性(例如,类使用types.MappingProxyType来阻止直接字典更新。)

     

如果没有参数,vars()就像locals()一样。请注意,本地词典仅对本地人的更新有用   字典被忽略了。

此外,我尝试并写了一个你可能感兴趣的装饰师。 这是一个类装饰器,它将initKwargs添加到它所装饰的类中。 此外,它还包装了该类的__init__方法,以便将它收到的kwargs字典附加到类中。 initKwargs属性。

def class_wrapper(cls):
    cls.initKwargs = []
    f = cls.__init__

    def wrapped_init(instance, **kwargs):
        cls.initKwargs.append(kwargs)
        return f(instance, **kwargs)            
    cls.__init__ = wrapped_init

    return cls

@class_wrapper
class Foo:
    def __init__(self, **kwargs):
        for k, v in kwargs.items():
            setattr(self, k, v)

演示:

>>> f1 = Foo()
>>> f2 = Foo(a=1, b=2)
>>> f3 = Foo(a=1, b=2, c=3, d=4)
>>> Foo.initKwargs
[{}, {'a': 1, 'b': 2}, {'a': 1, 'b': 2, 'c': 3, 'd': 4}]

我发现这种方法比使用vars要清晰得多,因为您知道自己定义后自己定义了什么。 它可以让你更好地掌控课程。行为。