De nos jours, le mot délégation est plus courant que l'héritage, il est donc courant de créer une classe qui encapsule un objet pour la délégation.
Dans un tel cas, la partie qui se branche sur cette instance devient problématique. (Pour cela, le code qui utilise une branche qui n'évite pas la saisie est bon en premier lieu Il y a aussi une histoire qu'il n'y a pas)
Est-il possible de tromper la branche de isinstance?
Comment puis-je tromper la branche d'une instance? Étonnamment facile, propriété appelée __class__
Si vous définissez, vous irez le voir lors de l'évaluation avec une instance.
Essayons le comportement ci-dessous. À propos du cas où l'objet User est encapsulé avec un objet Wrapper appelé LoggedWrapper. Je vérifie si je triche sur la branche de cette 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
À propos, puisque «class» existe dans l'objet Wrapper, le journal n'est pas sorti.
Recommended Posts