在类变量的类中调用类型(dict)函数(Python 3.4)

时间:2015-01-16 01:33:41

标签: python function class dictionary

我正在创建一个类,并尝试定义对应于.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”不会。

任何人都可以帮我解决这个问题吗?

2 个答案:

答案 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"}),它也将正常工作。但它可能会慢一些,因为其他方法不需要额外的函数调用。