关注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
类似,但我不确定这里出了什么问题,或者如何进一步剖析它。有什么想法吗?
答案 0 :(得分:2)
您应该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())
答案 1 :(得分:1)
您收到该错误是因为temperature()
调用返回None
,然后您尝试使用**
解压缩,就好像它是字典一样。因此,要使代码正常工作,您需要返回包含setter和amp;的相应字典。 getter方法。
我更喜欢摩西的解决方案,但是如果你真的想要的话,可以传递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
答案 2 :(得分:0)
确实我错过了return
函数定义中的temperature
语句。原始代码实际上包含行
return locals()
添加此行可使属性按预期工作。
答案 3 :(得分:0)
您定义的temperature
方法没有return语句,因此它隐式返回None
,这是您的错误消息中的...,not NoneType
。该方法确实有两个子方法,但这并不会导致它以任何形式返回它们,我认为你缺少一条线,如(未经测试):
return { "fget": fget, "fset": fset }
您还可以使用列表和单个*
。
话虽这么说,避免*
和**
魔法是最佳做法,但也有pylint rule来阻止它。