任何人都可以解释以下陌生感吗?
这可以按预期工作:
duncan@duncan:~/Working/wtf$ python -V
Python 2.7.3
duncan@duncan:~/Working/wtf$ cat test_without_get.py
class B(object):
def __setitem__(self, key, value):
print "__setitem__"
class A(object):
b = B()
a = A()
a.b
a.b[0] = 1
duncan@duncan:~/Working/wtf$ python test_without_get.py
__setitem__
但是这里__setitem__
打破并且似乎在其中调用了__get__
:
duncan@duncan:~/Working/wtf$ cat test_with_get.py
class B(object):
def __setitem__(self, key, value):
print "__setitem__"
def __get__(self, instance, owner):
print "__get__"
class A(object):
b = B()
a = A()
a.b
a.b[0] = 1
duncan@duncan:~/Working/wtf$ python test_with_get.py
__get__
__get__
Traceback (most recent call last):
File "test_with_get.py", line 12, in <module>
a.b[0] = 1
TypeError: 'NoneType' object does not support item assignment
任何人都有任何见解为什么会发生这种情况 以及如何解决它?
进一步的实验:
如ignacio-vazquez-abrams @所示,
如果__get__
返回一个对象,则事情按预期工作:
duncan@dunksbox:~/Working/wtf$ python -V
Python 2.7.3
duncan@dunksbox:~/Working/wtf$ cat test_with_get_working.py
class B(object):
def __setitem__(self, key, value):
print "__setitem__"
def __get__(self, instance, owner):
print "__get__"
return self
class A(object):
b = B()
a = A()
a.b
a.b[0] = 1
duncan@dunksbox:~/Working/wtf$ python ./test_with_get_working.py
__get__
__get__
__setitem__
但是,只有在您对__get__
返回的内容时要小心:
duncan@dunksbox:~/Working/wtf$ cat test_with_get_notworking.py
class B(object):
def __setitem__(self, key, value):
print "__setitem__"
def __get__(self, instance, owner):
print "__get__"
return [1]
class A(object):
b = B()
a = A()
a.b
a.b[0] = 1
duncan@dunksbox:~/Working/wtf$ python ./test_with_get_notworking.py
__get__
__get__
答案 0 :(得分:1)
之所以发生这种情况是因为您已将B
创建为描述符,因为它定义了一种描述符协议方法。围绕它的唯一方法是首先不将其创建为描述符,或者从__setitem__()
方法根据需要运行的描述符中返回单独的对象。