Python 如何在不知道类的名称的情况下获取类的属性
我有以下课程:Python 如何在不知道类的名称的情况下获取类的属性,python,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"}) 如何在不
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为我们提供了内置方法\uuuu getattribute\uuu
,但我仍然需要知道请求的属性的名称:
print(obj.__getattribute__("testkey1"))
\uuuu dict\uuu
属性保存您想要的内容。
班级有:
>>> 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})
您应该通过vars
内置函数访问此属性。
调用vars(foo)
将返回foo.\uuuu dict\uuuu
。
请参阅此相关帖子:
:
变量([对象])
返回模块、类、实例或任何其他具有\uuuuuuuu dict\uuu
属性的对象的\uuuuu dict\uuuuu
属性
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)
模块和实例等对象具有可更新的\uu dict\uu
属性;但是,其他对象可能对其
\uuuu dict\uuuu
属性(例如,类使用types.MappingProxyType
来防止直接更新字典)
没有参数,vars()
的行为类似于locals()
。注意,局部变量字典仅对读取有用,因为它更新了局部变量
字典被忽略了
此外,我还试着写了一个你可能感兴趣的装饰师。 这是一个类装饰器,它向它装饰的类添加一个
initKwargs
。
此外,它还包装了该类的\uuuu init\uuuu
方法,以便将它接收到的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
要干净得多,因为您自己定义了它,所以知道要访问什么。
它可以让你更好地控制班级的行为。你为什么要故意将自己置于这种情况下,而不是将其存储为
指令?@JonClements个人而言,我不知道,我的领导是这样计划的,我必须实现:停下来,随意告诉他们这不是一个好的设计,有点危险。。。人们将能够重击你已经使用过的名称,并破坏一些东西,以后调试它将变得非常糟糕。(或者相反,你可能会重击对他们传递的变量的赋值…)并且只需注意(在大多数用例中这是一个坏主意):你不会真的想使用obj.\uu getattribute\uuuu(“testkey1”)
-您将使用getattr(obj,'testkey1')
-不仅在眼睛和键盘上更容易操作,而且还允许在未找到属性时提供返回的默认值。如果您要建议,则建议使用vars(f)
-这里几乎不需要直接访问\uuuu dict\uuuu
,而且可能并不总是如预期的那样。@JonClements考虑到文档中关于变量的内容,它与\uu dict\uuu
有什么不同?我想我记得读过那篇文章,说得不太好,但我记不起为什么了……我记不清了。。。但是,vars(…)
将做正确的事情,而直接访问\uu dict\uuu
在某些情况下可能会失败。虽然我现在有点怀疑自己。。。但有一件事让我想起了:)此外——至少——在代码中没有dunder方法访问权,在不必要的地方总是好的。@JonClements我发现。因此,基本的论点是,由于Python为它提供了一个包装器,所以应该通过该包装器而不是直接访问它。这对我来说很有意义,很好的发现。谢谢现在-唯一的问题是,你不能真正告诉什么参数提供了,除非你拿走了那些已经在那里或知道你已经设置了。。。但是,如果老年退休金计划采取这种做法,那么,好吧,就在他们头上吧。