我对以下代码有一些疑问:
1 class Test(object):
2 def __init__(self):
3 print "Object instance created."
4 self._x = raw_input("Initial value of x = ")
5 print "Initial value of x set."
6
7 def Property(func):
8 return property(**func())
9
10 @Property
11 def x():
12 def fget(self):
13 print 'Getting x'
14 return self._x
15 def fset(self, val):
16 print 'Setting x'
17 self._x = val
18 def fdel(self):
19 print 'Deleting x'
20 del self._x
21 doc = "A test case"
22 return locals()
Property()
功能?return locals()
然后直接使用@property
作为装饰者?当我这样做时,我得到一个错误,说x没有参数,一个给出(大概是'自我')。我知道python有@x.setter
选项,但我不得不经常使用2.4,所以对我来说这不是一个选择。即便如此,@x.setter
似乎仍然不如在一个区块中定义所有内容。
有没有办法使用@property
在一个块中定义所有内容?
答案 0 :(得分:2)
您不能将property
直接用作您所发布的代码的装饰器,因为它不是设计为以这种方式使用,而且无法使用。
如果用作装饰器,property
会将函数转换为getter;如果用作函数,则可以传入getter,setter,deleter和doc。
locals()
会返回所有本地人,因此您将拥有一个包含fget
,fset
,fdel
,doc
的词典,Property
和__init__
- 导致property
爆炸,因为传递了太多参数。
就个人而言,我喜欢@x.setter
和@x.deleter
样式,因为我不会在类名空间中找到不必要的函数名。
如果你必须经常使用2.4,那么就自己滚动(或者像我一样偷取2.6中的最新版本):
class property(object):
"2.6 properties for 2.5-"
def __init__(self, fget=None, fset=None, fdel=None, doc=None):
self.fget = fget
self.fset = fset
self.fdel = fdel
self.__doc__ = doc or fget.__doc__
def __call__(self, func):
self.fget = func
if not self.__doc__:
self.__doc__ = fget.__doc__
def __get__(self, obj, objtype=None):
if obj is None:
return self
if self.fget is None:
raise AttributeError("unreadable attribute")
return self.fget(obj)
def __set__(self, obj, value):
if self.fset is None:
raise AttributeError("can't set attribute")
self.fset(obj, value)
def __delete__(self, obj):
if self.fdel is None:
raise AttributeError("can't delete attribute")
self.fdel(obj)
def setter(self, func):
self.fset = func
return self
def deleter(self, func):
self.fdel = func
return self
答案 1 :(得分:2)
你可以在一个块中完成所有操作:不是通过使用@property
来定义和实例化具有__get__()
,__set__()
和{{的类1}}方法。有关详细信息,请参阅Implementing Descriptors:
__delete__()
class Test(object):
def __init__(self):
print "Object instance created."
self._x = raw_input("Initial value of x = ")
print "Initial value of x set."
class x(object):
def __get__(self, instance, owner):
print 'Getting x'
return instance._x
def __set__(self, instance, value):
print 'Setting x'
instance._x = value
def __delete__(self, instance):
print 'Deleting x'
del instance._x
__doc__ = "A test case"
x = x()
是编写上述内容的快捷方式,示例类中的property()
方法是必须单独编写函数并将其传递给Property()
的快捷方式。相反,你编写一个定义函数的函数,然后返回它们,并将它们传递给property()
。
您无法使用property()
的原因是装饰器装饰单个对象。所以你需要一个容器,比如一个类,所以你也可以直接在那一点写一个描述符。