如何在python中实现__getitem__ dunder方法以获取属性值?

时间:2018-08-07 21:03:43

标签: python methods get attributes python-datamodel

我有以下代码:

class Personne:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __getitem__(self, *args):
        keys = list(*args)
        return [self.__dict__[key] for key in keys]


if __name__ == '__main__':
    p = Personne('A', 20)
    # age = p['age']
    # print(age)
    # name = p['name']
    # print(name)
    name, age = p['name', 'age']
    print(name, age)

未注释的部分可以正常工作,但是注释的代码中存在问题。 我如何实现所需的行为,即根据传递给 getitem 方法的参数(可以是一个或多个)来获取属性值。

谢谢。

2 个答案:

答案 0 :(得分:1)

如您所知,您的代码当前会返回错误,因为keys = list(*args)将字符串age视为可迭代字符串,并尝试寻找a,{{1 }}和g中的e。因此,您可以检查提供给self.__dict__的参数的类型,并对__getitem__进行适当的转换,以使args返回:

keys

输出将是class Personne: def __init__(self, name, age): self.name = name self.age = age def __getitem__(self, args): if isinstance(args, str): keys = [ args ] # args is a string else: keys = list(args) # args is a tuple return [self.__dict__[key] for key in keys] 中的值的列表。

答案 1 :(得分:1)

传递仅传递一个字符串的问题是,当您调用p ['age']时,* args的类型为字符串,因此list(* args)变为['a','g',' e']。当您同时传递“年龄”和“名称”时,* args将被解释为元组,并且您会得到适当的结果。解决此问题的一种方法是检查 getitem (自身,* args)方法中* args参数的类型。进行以下修改可以解决您面临的问题(Python 3),尽管您可能需要稍微清理一下。

class Personne:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __getitem__(self, *args):
        if isinstance(*args, str):
            return self.__dict__[str(*args)]
        keys = list(*args)
        return [self.__dict__[key] for key in keys]


if __name__ == '__main__':
    p = Personne('A', 20)
    age = p['age']
    print(age)
    name = p['name']
    print(name)
    name, age = p['name', 'age']
    print(name, age)
    
    
CONSOLE OUTPUT : 

20
A
A 20