我有一个名为User的课程:
class User(object):
def __init__(self, arg1, ..., traits = None):
self.arg1 = arg1
...
self.traits = traits
用户有一个属性traits
,这是一个字典。当我需要保存关于除了电子邮件地址,用户ID等基本内容之外的用户的更多信息时,我可以填充这些内容。
创建Traits
类并使用__init__
设置setattr
中的属性会更高效还是更低效?查找工作会更好吗?这台机器会给我带来什么东西,或者它最终只是更多的工作?
答案 0 :(得分:2)
您可以直接修改实例__dict__
(假设它没有实现__slots__
或任何愚蠢的事情)
这是一个简单的例子:
class Traits(object):
pass
class User(object):
def __init__(self,**traits):
self.traits = Traits()
self.traits.__dict__.update(traits)
a = User(eye_color="blue")
print a.traits.eye_color
当然,只有这样做才有可能更安全(但效率稍差):
class User(object):
def __init__(self,**traits):
self.traits = Traits()
for k,v in traits.items():
setattr(traits,k,v)
实际上只有一行代码可以提供相同的API。它更安全,因为你永远不知道有人做了什么来混淆Traits
以提供各种描述符(例如属性)等。setattr
将正确地做所有这些事情,盲目地写__dict__
可能是可能有害。
答案 1 :(得分:2)
对我来说很好,我很想重写:
class User(object):
def __init__(self, arg1, arg2, **traits):
self.arg1 = arg1
self.arg2 = arg2
self.traits = traits
如果您真的想要,那么如果找不到属性,您可以覆盖以回溯到特征字典:
def __getattr__(self, name):
return self.traits[name]
示例:
>>> u = User(1, 2, email='something')
>>> y = User(1, 2, email='bob', telno='999')
>>> u.arg1, u.arg2, u.email
(1, 2, 'something')
>>> y.arg1, y.arg2, y.email, y.telno
(1, 2, 'bob', '999')
>>> y.arg1, y.arg2, y.email, y.something
Traceback (most recent call last):
File "<pyshell#105>", line 1, in <module>
y.arg1, y.arg2, y.email, y.something
File "/home/jon/adfafasdf.py", line 7, in __getattr__
return self.traits[name]
KeyError: 'something'
所以你可能希望把它变成一个更明智的错误,并改为:
def __getattr__(self, name):
try:
return self.traits[name]
except KeyError as e:
raise AttributeError() # with suitably formatted string