Nowadays, the word delegation is more common than inheritance, so it's common to create a class that wraps an object for delegation.
In such a case, the part that branches at is instance becomes troublesome. (For this, code that uses a branch that does not do duck typing in the first place is good. There is also a story that there is no)
Is it possible to cheat the branch of isinstance?
How can I cheat the branch of is instance? Surprisingly easy and the property __class__
If you define, you will go to see it when evaluating with is instance.
Let's try the behavior below. About the case where the User object is wrapped with a Wrapper object called LoggedWrapper. I'm checking if I'm cheating on the branch of is instance.
# -*- coding:utf-8 -*-
import logging
logger = logging.getLogger(__name__)
class LoggedWrapper(object):
def __init__(self, ob):
self.ob = ob
def __getattr__(self, k):
logger.debug("action:%s", k)
return getattr(self.ob, k)
@property
def __class__(self):
return self.ob.__class__
from collections import namedtuple
User = namedtuple("User", "name age")
user = User("foo", 20)
wrapped = LoggedWrapper(user)
logging.basicConfig(level=logging.NOTSET)
print(wrapped.name)
print(wrapped.age)
# DEBUG:__main__:action:name
# foo
# DEBUG:__main__:action:age
# 20
print(isinstance(wrapped, User))
# True
By the way, since __class__
exists in the Wrapper object, log is not output.
Recommended Posts