您可以初始化类字典通过构造函数:
def __init__(self,**data):
,并调用它,如下所示:
f = MyClass(**{'a': 'v1', 'b': 'v2'})
所有实例的属性被访问(读)在__setattr__,需要利用其母公司(超)方法是宣布,只一次:
super().__setattr__('NewVarName1', InitialValue)
或者
super().__setattr__('data', dict())
此之后,它们可以被访问或以通常的方式分配给:
self.x = 1
:
self.data = data
属性和实例属性不被访问在__setattr__,可以以通常的方式被声明
重写的__setattr__方法现在必须在其自身内部调用父方法,以便声明新变量:
super().__setattr__(key,value)
一个完整的类将如下所示:
class MyClass(object):
def __init__(self, **data):
# The variable self.data is used by method __setattr__
# inside this class, so we will need to declare it
# using the parent __setattr__ method:
super().__setattr__('data', dict())
self.data = data
# These declarations will jump to
# super().__setattr__('data', dict())
# inside method __setattr__ of this class:
self.x = 1
self.y = 2
def __getattr__(self, name):
# This will callback will never be called for instance variables
# that have beed declared before being accessed.
if name in self.data:
# Return a valid dictionary item:
return self.data[name]
else:
# So when an instance variable is being accessed, and
# it has not been declared before, nor is it contained
# in dictionary 'data', an attribute exception needs to
# be raised.
raise AttributeError
def __setattr__(self, key, value):
if key in self.data:
# Assign valid dictionary items here:
self.data[key] = value
else:
# Assign anything else as an instance attribute:
super().__setattr__(key,value)
测试:
f = MyClass(**{'a': 'v1', 'b': 'v2'})
print("f.a = ", f.a)
print("f.b = ", f.b)
print("f.data = ", f.data)
f.a = 'c'
f.d = 'e'
print("f.a = ", f.a)
print("f.b = ", f.b)
print("f.data = ", f.data)
print("f.d = ", f.d)
print("f.x = ", f.x)
print("f.y = ", f.y)
# Should raise attributed Error
print("f.g = ", f.g)
输出:
f.a = v1
f.b = v2
f.data = {'a': 'v1', 'b': 'v2'}
f.a = c
f.b = v2
f.data = {'a': 'c', 'b': 'v2'}
f.d = e
f.x = 1
f.y = 2
Traceback (most recent call last):
File "MyClass.py", line 49, in <module>
print("f.g = ", f.g)
File "MyClass.py", line 25, in __getattr__
raise AttributeError
AttributeError
理想的情况下,一点都没有。 ;-) – delnan 2013-04-26 13:28:18
你可能不想在实践中这样做。如果您的数据属于字典,请使用字典;如果你的数据属于一个对象,使用一个对象。无论如何,['namedtuple'](http://docs.python.org/3.3/library/collections.html#namedtuple-factory-function-for-tuples-with-named-fields),其工作方式类似于轻量级的对象,可能会做你想做的。 – 2013-04-26 13:30:50
请记住'__getattr__'仅用于缺少属性查找。 – Kos 2013-04-26 13:37:04