我編寫了一個metaclass
,它定義了在運行時使用它的類的屬性。它只是讓從REQUIRED_KEYS這些屬性的屬性,然後宣佈property
,例如:在Python中使用元類,setattr和屬性以及奇怪的行爲
class Base(object):
REQUIRED_KEYS =()
class __metaclass__(type):
def __init__(cls, name, bases, nmspc):
type.__init__(cls, name, bases, nmspc)
for attr in cls.REQUIRED_KEYS:
setattr(cls, attr, property(lambda self: self._dict.get(attr, None)))
def __init__(self, **kwargs):
self._dict = dict(**kwargs)
class Config(Base):
REQUIRED_KEYS = ('foo', 'bar')
如果一個鍵沒有給出在運行時定義的屬性返回None
值。我會預期正確的行爲以下執行,返回1
和None
:
config = Config(**{'foo': 1})
config.foo
config.bar
但對於foo
屬性在正確的價值預計將1
返回無。
如果我通過一個閉包修改property
函數使用的lambda
,如下面的代碼片段所示,它工作正常。
class __metaclass__(type):
def __init__(cls, name, bases, nmspc):
def get(attr):
def _get(self):
return self._dict.get(attr, None)
return _get
type.__init__(cls, name, bases, nmspc)
for attr in cls.REQUIRED_KEYS:
setattr(cls, attr, property(get(attr)))
繼第一個片段的執行,我意識到,lambda函數總是調用最後attr
值。這意味着當我們試圖訪問foo
屬性時,lambda使用bar
值。
有人知道這裏發生了什麼嗎?
謝謝,我沒有在這裏參考瞭解這個問題。 – pfreixes