Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Faking whether an object is an Instance of a Class in Python

Suppose I have a class FakePerson which imitates all the attributes and functionality of a base class RealPerson without extending it. In Python 3, is it possible to fake isinstance() in order to recognise FakePerson as a RealPerson object by only modifying the FakePerson class. For example:

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))

The context of this is suppose I have a class that imitates most / all of the functionality of a Pandas DataFrame row (a namedtuple object). If I have a list of rows list_of_rows, Pandas generates a DataFrame object by pandas.DataFrame(list_of_rows). However, since each element in list_of_rows is not a namedtuple and just a 'fake', the constructor can't recognise these 'fake' row objects as real rows even if the fake object does fake all the underlying methods and attributes of the Pandas namedtuple.

like image 674
Bentley Carr Avatar asked Dec 08 '25 11:12

Bentley Carr


1 Answers

You may need to subclass your RealPerson class.

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))

Hope this answer would not be too late for you LOL

like image 168
Autumnii Avatar answered Dec 10 '25 01:12

Autumnii