我正在创建一个类,并尝试定义对应于.keys()或.values()等函数的类变量,这些函数在另一个类变量上调用。 例如:
class DATA(object):
def __init__(self, id, database = {}):
self.id = id
self.database = database
self.addresses = database.keys()
self.data = database.values()
这似乎不起作用,就像我创建类
的实例一样foo = DATA(0,{"a":1,"b":2})
然后要求:
print(foo.addresses)
>>> []
它会返回一个空列表。
注意:
在我的实际程序中,我开始使用任何类实例的空字典,然后我使用函数添加到字典中。在这种情况下,调用“.database”仍然有效,但“.addresses”不会。
任何人都可以帮我解决这个问题吗?
答案 0 :(得分:1)
我不确定这是否是问题,但使用诸如{}之类的可变作为默认参数通常会导致错误。请参阅:"Least Astonishment" and the Mutable Default Argument
这更安全:
def __init__(self, id, database=None):
if database is None:
self.database = {}
else:
self.database = database
我不明白DATA.addresses和DATA.data的目的。您可以使用属性装饰器的函数来避免冗余吗?
@property:
def addresses(self):
return self.database.keys()
@property:
def data(self):
return self.database.values()
答案 1 :(得分:1)
问题是您在keys
方法中正确调用__init__
并保存结果。您想要做的只是在您想要访问时调用keys
。
现在,根据课程要求,您可以通过几种不同的方式完成此任务。
如果您不介意公开更改调用代码,可以使其变得非常简单,只需使用foo.database.keys()
而不是foo.addresses
。后者并不需要存在,因为它包含的所有信息都已通过databases
属性的方法获得。
另一种方法是将绑定实例方法database.keys
保存到DATA
对象的实例变量中(不调用它):
class DATA(object)
def __init__(self, database=None):
if database is None:
database = {}
self.database = database
self.addresses = database.keys # don't call keys here!
在调用代码中,您使用foo.addresses
代替foo.addresses()
(函数调用,而不仅仅是属性查找)。这看起来像是对DATA实例的方法调用,尽管它并不是真的。它在数据库字典上调用已绑定的方法。如果其他代码可能完全替换database
字典(而不是仅仅在其中进行变更),这可能会中断。
最后一种方法是当用户尝试访问property
实例的keys
属性时,使用addresses
从数据库dict请求DATA
:< / p>
class DATA(object)
def __init__(self, database=None):
if database is None:
database = {}
self.database = database
# don't save anything as "addresses" here
@property
def addresses(self):
return self.database.keys()
这可能是最好的,因为它允许调用代码将addresses
视为属性。如果您完全替换其他代码中的database
对象(例如foo.database = {"foo":"bar"}
),它也将正常工作。但它可能会慢一些,因为其他方法不需要额外的函数调用。