class MyClass(object):
def __init__(self):
# prevents infinite recursion from self.data = {'a': 'v1', 'b': 'v2'}
# as now we have __setattr__, which will call __getattr__ when the line
# self.data[k] tries to access self.data, won't find it in the instance
# dictionary and return self.data[k] will in turn call __getattr__
# for the same reason and so on.... so we manually set data initially
super(MyClass, self).__setattr__('data', {'a': 'v1', 'b': 'v2'})
def __setattr__(self, k, v):
self.data[k] = v
def __getattr__(self, k):
# we don't need a special call to super here because getattr is only
# called when an attribute is NOT found in the instance's dictionary
try:
return self.data[k]
except KeyError:
raise AttributeError
>>> ob = MyClass()
>>> ob.c = 1
>>> ob.c
1
如果不需要设置属性,只需使用namedtuple
例如
>>> from collections import namedtuple
>>> MyClass = namedtuple("MyClass", ["a", "b"])
>>> ob = MyClass(a=1, b=2)
>>> ob.a
1
如果需要默认参数,可以在其周围编写一个包装类:
class MyClass(namedtuple("MyClass", ["a", "b"])):
def __new__(cls, a="v1", b="v2"):
return super(MyClass, cls).__new__(cls, a, b)
或者它作为一个函数看起来更好:
def MyClass(a="v1", b="v2", cls=namedtuple("MyClass", ["a", "b"])):
return cls(a, b)
def __getattr__(self, attrName):
if not self.__dict__.has_key(attrName):
value = self.fetchAttr(attrName) # computes the value
self.__dict__[attrName] = value
return self.__dict__[attrName]
但是,在实现
__setattr__
时要小心,您需要做一些修改:如果不需要设置属性,只需使用namedtuple 例如
如果需要默认参数,可以在其周围编写一个包装类:
或者它作为一个函数看起来更好:
很晚才去参加派对,但找到了两个很好的资源来更好地解释这一点(IMHO)。
如here所述,您应该使用
self.__dict__
从__getattr__
中访问字段,以避免无限递归。提供的示例如下:注意:在第二行(上面),一个更像Python的方法是(
has_key
显然在Python 3中被删除了):other resource解释了
__getattr__
只在对象中找不到属性时调用,并且hasattr
如果有__getattr__
的实现,则始终返回True
。它提供了以下示例来演示:相关问题 更多 >
编程相关推荐