[英]Implementing a property using the double asterisk (**)
在http://www.programiz.com/python-programming/property之后,我熟悉以下在Python中實現屬性的方法:
class Celsius(object):
def __init__(self, temperature = 0):
self._temperature = temperature
def get_temperature(self):
print("Getting value")
return self._temperature
def set_temperature(self, value):
if value < -273:
raise ValueError("Temperature below -273 is not possible")
print("Setting value")
self._temperature = value
temperature = property(get_temperature, set_temperature)
我現在正在閱讀一些代碼,其中使用雙星號( **
)來定義屬性。 如果我將其調整為適合自己的示例,則它看起來像這樣:
class Celsius(object):
def __init__(self, temperature = 0):
self._temperature = temperature
def temperature():
def fget(self):
print("Getting value")
return self._temperature
def fset(self, value):
if value < -273:
raise ValueError("Temperature below -273 is not possible")
print("Setting value")
self._temperature = value
temperature = property(**temperature())
但是,如果我嘗試運行此代碼並通過c = Celsius()
實例化一個類,則會得到
TypeError: type object argument after ** must be a mapping, not NoneType
據我所知, fget
和fset
是關鍵字參數property
,所以我希望什么出來的**temperature()
是像fget=fget, fset=fset
,但我不知道這到底是怎么還是走錯了如何進一步剖析。 有任何想法嗎?
您應該return
嵌套函數,然后根據函數調用將其解壓縮:
class Celsius(object):
def __init__(self, temperature = 0):
self._temperature = temperature
def temperature():
...
return fget, fset
temperature = property(*temperature())
如果您堅持使用**
,那么您將從函數中返回映射/字典,然后將其解壓縮為關鍵字參數。
def temperature():
...
return {'fget': fget, 'fset': fset}
temperature = property(**temperature())
之所以會出現此錯誤,是因為temperature()
調用返回None
,然后您嘗試使用**
將其解包為字典。 因此,要使該代碼正常工作,您需要返回一個包含setter和getter方法的適當字典。
我更喜歡Moses的解決方案,但是如果您確實願意, 可以使用dict而不是元組傳遞方法。 例如,
class Celsius(object):
def __init__(self, temperature = 0):
self._temperature = temperature
def temperature():
def fget(self):
print("Getting value")
return self._temperature
def fset(self, value):
if value < -273:
raise ValueError("Temperature below -273 is not possible")
print("Setting value")
self._temperature = value
return {'fget': fget, 'fset': fset}
temperature = property(**temperature())
# Test
a = Celsius()
a.temperature = 20
print(a.temperature)
產量
Setting value
Getting value
20
確實,我錯過了temperature
函數定義中的return
語句。 原始代碼實際上包含該行
return locals()
添加此行使該屬性按預期工作。
您定義的temperature
方法沒有return語句,因此它隱式返回None
,這是錯誤消息中的...,not NoneType
。 該方法確實有兩個子方法,但是這不會導致它以任何形式返回它們,我認為您缺少諸如(untested)之類的行:
return { "fget": fget, "fset": fset }
您還可以使用一個列表和一個*
。
話雖如此,這是避免*
和**
魔術的最佳實踐,也有防止這種情況的柔道規則 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.