1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

isinstanceもごまかすfakeclassを作る

1
Last updated at Posted at 2015-02-18

まえがき

継承より委譲という言葉も当たり前の言葉になっているような昨今、委譲のためにあるオブジェクトをwrapしたクラスを作るということはよくありますね。

そのような場合にisinstanceで分岐している部分が厄介になったりするのですが。(これに関してはそもそもducktypingを行わない分岐を使うコードが良く
ないという話もあります)

isinstanceの分岐をごまかすことは出来るでしょうか?

__class__というpropertyを定義する。

isinstanceの分岐をごまかすにはどうすれば良いかということですが。意外と簡単で __class__ というproperty
を定義してあげればisinstanceで評価する際にそちらを見に行きます。

確認のためのコード

以下で挙動を試してみることにします。UserオブジェクトをLoggedWrapperというWrapperオブジェクトでwrapした場合について。
isinstanceの分岐をごまかせているか確認しています。

# -*- 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

ちなみに __class__ はWrapperオブジェクトに存在しているためlogは出力されません。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?