【问题标题】:Faking whether an object is an Instance of a Class in Python在 Python 中伪造一个对象是否是一个类的实例
【发布时间】:2020-07-14 20:52:34
【问题描述】:

假设我有一个类FakePerson,它模仿了基类RealPerson 没有扩展它的所有属性和功能。在 Python 3 中,是否可以通过仅修改 FakePerson 类来伪造 isinstance() 以便将 FakePerson 识别为 RealPerson 对象。例如:

class RealPerson():
    def __init__(self, age):
        self.age = age

    def are_you_real(self):
        return 'Yes, I can confirm I am a real person'

    def do_something(self):
        return 'I did something'

    # Complicated functionality here

class FakePerson(): # Purposely don't extend RealPerson
    def __init__(self, hostage):
        self.hostage = hostage

    def __getattr__(self, name):
        return getattr(self.hostage, name)

    def do_something(self):
        return 'Ill pretend I did something'

    # I don't need complicated functionality since I am only pretending to be a real person.


a = FakePerson(RealPerson(30))
print(isinstance(a, RealPerson))

假设我有一个类可以模仿 Pandas DataFrame 行(namedtuple 对象)的大部分/所有功能。如果我有一个行列表list_of_rows,Pandas 会通过pandas.DataFrame(list_of_rows) 生成一个 DataFrame 对象。但是,由于list_of_rows 中的每个元素都不是namedtuple,而只是一个“假”,因此即使假对象确实伪造了所有底层方法和属性,构造函数也无法将这些“假”行对象识别为真实行熊猫namedtuple.

【问题讨论】:

  • 这听起来像是一个巨大的 xy 问题。您应该考虑单独提出您的实际问题,因为这个问题本身就很有趣,即使它不是您实际问题的最佳解决方案。

标签: python pandas dataframe isinstance


【解决方案1】:

您可能需要继承您的 RealPerson 类。

class RealPerson:
    def __init__(self, age):
        self.age = age

    def are_you_real(self):
        return 'Yes, I can confirm I am a real person'

    def do_something(self):
        return 'I did something'

    # Complicated functionality here

class FakePerson: # Purposely don't extend RealPerson
    def __init__(self, hostage):
        self.hostage = hostage

    def __getattr__(self, name):
        return getattr(self.hostage, name)

    def do_something(self):
        return 'Ill pretend I did something'

    # I don't need complicated functionality since I am only pretending to be a real person.


class BetterFakePerson(RealPerson):
    pass

BetterFakePerson.__init__ = FakePerson.__init__
BetterFakePerson.__getattr__ = FakePerson.__getattr__
BetterFakePerson.do_something = FakePerson.do_something

a = FakePerson(RealPerson(30))
print(isinstance(a, RealPerson))

b = BetterFakePerson(RealPerson(30))
print(isinstance(b, RealPerson))

希望这个答案对你来说不会太晚,哈哈

【讨论】:

    【解决方案2】:

    isInstance() 函数是一个 python 内置函数,它的实现显式查找对象的(直接、间接或虚拟)类或子类。您所指的“模仿”也称为duck typing。在您的情况下,您似乎 确实 想要扩展或子类化 DataFrame 行。虽然,您可能可以避免分配 class 属性,但要知道这可能会导致未定义的行为,因为它是特定于实现的。

    【讨论】:

    • 鉴于这是 python,我只是认为你的挖掘不够深入。
    猜你喜欢
    • 1970-01-01
    • 2013-04-01
    • 2012-08-14
    • 2012-03-02
    • 2019-09-29
    • 1970-01-01
    • 2012-02-18
    • 2015-02-13
    • 1970-01-01
    相关资源
    最近更新 更多