This issue tracker has been migrated to GitHub ,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2011年05月03日 20:47 by r.david.murray, last changed 2022年04月11日 14:57 by admin. This issue is now closed.
| Messages (5) | |||
|---|---|---|---|
| msg135068 - (view) | Author: R. David Murray (r.david.murray) * (Python committer) | Date: 2011年05月03日 20:47 | |
The following code:
--------------------------------
class X(list):
def __contains__(self, key):
print('X contains:', key)
class Y():
def __init__(self, x):
self.x = x
def __getattr__(self, key):
return getattr(self.x, key)
def __iter__(self):
print('Y iter')
return iter([1,2])
x = X()
y = Y(x)
print('res:', 1 in y)
-----------------------------
prints True. It has been explained to me that this is because of:
http://docs.python.org/reference/datamodel.html#special-method-lookup-for-new-style-classes
However, there is no way in the world that I would guess the behavior above from the documentation provided (and I find it surprising...I expected x's __contains__ to get called because Y (a class, not an instance) doesn't have a __contains__ method).
Can anyone explain it more clearly and update the documentation?
|
|||
| msg135074 - (view) | Author: Eric Snow (eric.snow) * (Python committer) | Date: 2011年05月03日 21:18 | |
In 2.7 I get the following (if Y does not inherit from object):
>>> print('res:', 1 in y)
('X contains:', 1)
('res:', False)
This makes sense with old style classes. With Y(object):
>>> print('res:', 1 in y)
Y iter
('res:', True)
|
|||
| msg135075 - (view) | Author: Georg Brandl (georg.brandl) * (Python committer) | Date: 2011年05月03日 21:19 | |
Not sure I understand your issue here. How should "1 in y" get at X.__contains__ given the special method lookup rules? The __getattr__ is not called since y.__contains__ isn't looked up. |
|||
| msg135080 - (view) | Author: R. David Murray (r.david.murray) * (Python committer) | Date: 2011年05月03日 21:43 | |
Well, then I suppose my question is why isn't __contains__ looked up? Other special methods that don't exist on Y do cause __getattr__ to be called. Why is __contains__ special? The docs for __getattr__ don't hint at this possibility either. I think the people that understand this must have a mental model of how the interpreter looks up methods that has some pieces that are missing from mine. I guess I'd like those bits to be made explicit in the special method lookup docs, or if they are already documented somewhere, for there to be a pointer to them in the special method lookup docs. |
|||
| msg135082 - (view) | Author: R. David Murray (r.david.murray) * (Python committer) | Date: 2011年05月03日 22:01 | |
Ah, that's what my problem is. My test example was poorly conceived (I used __del__!) so I *thought* the other special methods were triggering getattr. I'd have figured it out if I hadn't screwed up my test :( |
|||
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2022年04月11日 14:57:16 | admin | set | github: 56197 |
| 2011年05月03日 22:01:55 | r.david.murray | set | status: open -> closed resolution: not a bug messages: + msg135082 stage: needs patch -> resolved |
| 2011年05月03日 21:43:39 | r.david.murray | set | messages: + msg135080 |
| 2011年05月03日 21:19:18 | georg.brandl | set | nosy:
+ georg.brandl messages: + msg135075 |
| 2011年05月03日 21:18:11 | eric.snow | set | nosy:
+ eric.snow messages: + msg135074 |
| 2011年05月03日 20:56:10 | rhettinger | set | assignee: docs@python -> rhettinger nosy: + rhettinger |
| 2011年05月03日 20:49:04 | Trundle | set | nosy:
+ Trundle |
| 2011年05月03日 20:47:09 | r.david.murray | create | |