class Silly:
@property
def silly(self):
"This is a silly property"
print("You are getting silly")
return self._silly
@silly.setter
def silly(self, value):
print("You are making silly {}".format(value))
self._silly = value
@silly.deleter
def silly(self):
print("Whoah, you killed silly!")
del self._silly
s = Silly()
s.silly = "funny"
value = s.silly
del s.silly
Run Code Online (Sandbox Code Playgroud)
但它没有打印出"你变得愚蠢","你正在制造愚蠢的搞笑",......正如预期的那样.不知道为什么.亲爱的,你能让我弄清楚吗?
提前致谢!
我有两个类,一个是"就地操作符"覆盖(比如说+=),另一个是通过a公开第一个实例@property.(注意:从我的实际代码到再现问题的最小代码,这大大简化了.)
class MyValue(object):
def __init__(self, value):
self.value = value
def __iadd__(self, other):
self.value += other
return self
def __repr__(self):
return str(self.value)
class MyOwner(object):
def __init__(self):
self._what = MyValue(40)
@property
def what(self):
return self._what
Run Code Online (Sandbox Code Playgroud)
现在,当我尝试在公开的属性上使用该运算符时:
>>> owner = MyOwner()
>>> owner.what += 2
AttributeError: can't set attribute
Run Code Online (Sandbox Code Playgroud)
从我发现这是预期的,因为它试图设置属性owner. 有没有办法防止将属性设置为新对象,同时仍然允许我(就地)修改它后面的对象,或者这只是语言的怪癖?
(另请参阅此问题,但我试图采用其他方式,最好不要回到旧式类,因为最终我希望它能与Python 3一起使用.)
与此同时,我用一种方法做了同样的事情.
class MyValue(object):
# ...
def add(self, other):
self.value += other
>>> …Run Code Online (Sandbox Code Playgroud) python properties new-style-class python-2.7 augmented-assignment
在Python文档,各国__getattribute__可以查找特殊的方法时被绕过。这是通过语言语法或内置函数进行隐式调用的结果。
例如,
elem = container[0]
Run Code Online (Sandbox Code Playgroud)
不等同于:
elem = container.__getattribute__('__getitem__')[0]
Run Code Online (Sandbox Code Playgroud)
下面是另一个例子:
class WrappedList:
def __init__(self):
object.__setattr__(self, 'interal_list', ['apple', 'pear', 'orange'])
def __getattribute__(self, attr_name):
interal_list = object.__getattribute__(self, 'interal_list')
attr = getattr(interal_list, attr_name)
return attr
wl = WrappedList()
print("\nSTART TEST 01 ------------------------")
try:
print(wl[0]) # throws TypeError: 'WrappedList' object does not support indexing
except TypeError as e:
print(e)
print("\nSTART TEST 02 ------------------------")
try:
getitem = getattr(wl, '__getitem__')
print(getitem(0)) # works just fine
except TypeError as e:
print(e)
Run Code Online (Sandbox Code Playgroud)
我想编写一个名为的MagicOverrider …
由于 Python 力求找到一种正确的方式,我想知道 property.getter 的目的是什么。在这个例子中,WhyMe 定义了一个 getter,但 Other 没有,所以我想知道 property.getter 的重点是什么,只是使用属性。
class WhyMe(object):
def __init__(self):
self._val = 44
@property
def val(self):
print 'I am not called'
return self._val
@val.getter # What advantage do I bring?
def val(self):
print 'getter called'
return self._val
class Other(object):
def __init__(self):
self._val = 44
@property
def val(self):
print 'I AM called'
return self._val
Run Code Online (Sandbox Code Playgroud)
并使用它们:
>>> why = WhyMe()
>>> why.val
getter called
44
>>> other = Other()
>>> other.val
I AM called
44
Run Code Online (Sandbox Code Playgroud)
我对属性并不陌生,我只是想知道制作吸气剂是否有一些优势,或者只是为了对称而放在那里?
为了获得所有定义的类属性,我尝试使用
TheClass.__dict__
Run Code Online (Sandbox Code Playgroud)
但这也给了我特殊的属性。有没有办法只获得自定义属性,还是我必须自己“清理”字典?
根据Python 2.7.12文档:
\n\n\n\n\n如果
\n__setattr__()想要分配给实例属性,则不应简单地执行self.name = value\xe2\x80\x94,否则会导致对其自身的递归调用。相反,它应该将值插入到实例属性的字典中,例如self.__dict__[name] = value。对于新式类,不应访问实例字典,而应调用基类的同名方法,例如object.__setattr__(self, name, value)。
然而,下面的代码可以正常工作:
\n\nclass Class(object):\n def __setattr__(self, name, val):\n self.__dict__[name] = val;\n\nc = Class()\nc.val = 42\nprint c.val\nRun Code Online (Sandbox Code Playgroud)\n\n我知道super(Class, obj).__setattr__(name, value)可以确保__setattr__所有基类的方法都被调用,但是经典类也可以从基类继承。那么为什么只推荐新风格的课程呢?
或者,另一方面,为什么经典课程不建议这样做?
\npython ×6
class ×3
properties ×2
decorator ×1
inheritance ×1
metaclass ×1
oop ×1
python-2.7 ×1
python-3.x ×1
setattr ×1