getatribute怎么写才能返回dict中的变量?
How to write getatrribute so that variables in dict can be returned?
我有一个class,里面有一个dict。我想通过直接 "instance.key" 而不是 "instance.d[key]" 来访问字典中的变量。怎么做?
class A:
def __init__(self):
self.a = 1
self.b = 2
self.fields = {'c': 3, 'd': 4}
def main():
a = A()
print(a.a) # 1
print(a.b) # 2
print(a.c) # currently raise Exception, I want it to print 3
print(a.d) # currently raise Exception, I want it to print 4
if __name__ == '__main__':
main()
您可以覆盖 object.__getattr__(self, name)
方法(可以定义此类方法以自定义 class 实例的属性访问的含义):
class A:
def __init__(self):
self.a = 1
self.b = 2
self.fields = {'c': 3, 'd': 4}
def __getattr__(self, item):
return self.__dict__.get(item) or self.__dict__['fields'].get(item)
a = A()
print(a.a) # 1
print(a.b) # 2
print(a.c) # 3
print(a.d) # 4
参考link:__getattr__
你还可以修改__dict__
:
class A:
def __init__(self):
self.a = 1
self.b = 2
self.fields = {'c': 3, 'd': 4}
self.__dict__ = {**self.__dict__, **self.fields}
现在:
def main():
a = A()
print(a.a)
print(a.b)
print(a.c)
print(a.d)
if __name__ == '__main__':
main()
给出:
1
2
3
4
按照@RomanPerekhrest 的建议实施__getattr__
。您可能遇到的唯一问题是您的实例属性覆盖了您的字典条目。如果这不是预期的行为,您应该实施 __getattribute__
而不是 __getattr__
像这样:
class A:
def __init__(self):
self.a = 1
self.b = 2
self.e = 5
self.fields = {'c': 3, 'd': 4, 'e': 6}
def __getattribute__(self, key):
fields = super().__getattribute__('fields')
if key == 'fields':
return fields
try:
return fields[key]
except KeyError:
return super().__getattribute__(key)
a = A()
print(a.a) # 1
print(a.b) # 2
print(a.c) # 3
print(a.d) # 4
print(a.e) # 6 (Note that it returns the entry of the dict rather that the instance attribute)
print(a.f) # Raises exception (not in the instance attributes nor in the dict)
我有一个class,里面有一个dict。我想通过直接 "instance.key" 而不是 "instance.d[key]" 来访问字典中的变量。怎么做?
class A:
def __init__(self):
self.a = 1
self.b = 2
self.fields = {'c': 3, 'd': 4}
def main():
a = A()
print(a.a) # 1
print(a.b) # 2
print(a.c) # currently raise Exception, I want it to print 3
print(a.d) # currently raise Exception, I want it to print 4
if __name__ == '__main__':
main()
您可以覆盖 object.__getattr__(self, name)
方法(可以定义此类方法以自定义 class 实例的属性访问的含义):
class A:
def __init__(self):
self.a = 1
self.b = 2
self.fields = {'c': 3, 'd': 4}
def __getattr__(self, item):
return self.__dict__.get(item) or self.__dict__['fields'].get(item)
a = A()
print(a.a) # 1
print(a.b) # 2
print(a.c) # 3
print(a.d) # 4
参考link:__getattr__
你还可以修改__dict__
:
class A:
def __init__(self):
self.a = 1
self.b = 2
self.fields = {'c': 3, 'd': 4}
self.__dict__ = {**self.__dict__, **self.fields}
现在:
def main():
a = A()
print(a.a)
print(a.b)
print(a.c)
print(a.d)
if __name__ == '__main__':
main()
给出:
1
2
3
4
按照@RomanPerekhrest 的建议实施__getattr__
。您可能遇到的唯一问题是您的实例属性覆盖了您的字典条目。如果这不是预期的行为,您应该实施 __getattribute__
而不是 __getattr__
像这样:
class A:
def __init__(self):
self.a = 1
self.b = 2
self.e = 5
self.fields = {'c': 3, 'd': 4, 'e': 6}
def __getattribute__(self, key):
fields = super().__getattribute__('fields')
if key == 'fields':
return fields
try:
return fields[key]
except KeyError:
return super().__getattribute__(key)
a = A()
print(a.a) # 1
print(a.b) # 2
print(a.c) # 3
print(a.d) # 4
print(a.e) # 6 (Note that it returns the entry of the dict rather that the instance attribute)
print(a.f) # Raises exception (not in the instance attributes nor in the dict)