您可以初始化類字典通過構造函數:
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