k88
k88

Reputation: 1934

Get attributibutes in only base class (Python)

I have the following class structures:

class Parent(object):
    def __init__(self, id, name):
        self.id = id
        self.name = name

    def print_vars(self):
        print(vars(self))

class Child(Parent):
    def __init__(self, id, name, last_name, age):
       Parent.__init__(self, id, name)
       self.last_name = last_name
       self.age = age

class AnotherChild(Parent):
    def __init__(self, id, name, address):
       Parent.__init__(self, id, name)
       self.address= address

Perhaps not the best example, but I hope enough to get the idea accross. The idea is that I initialise two seperate instances that share some common attributes and methods. I need to be able to dump both objects into some json and csv files which I hope to achieve with the method dump_to_file (replaced by print_vars in this example). Now this method worked fine when I had to dump all the attributes from both the parent and child classes to a single file. Howeer, I want to only dump the attributes from the parent class. I tried to replace self by super or super(Parent, self) but without much success. What is the best way to access only the attributes from the class the code is written in?

I believe Java would do this automatically as the method is defined in the parent class, and the parent class does not know the child class attributes.

Upvotes: 3

Views: 343

Answers (2)

Mikhail_Sam
Mikhail_Sam

Reputation: 11248

I face the same problem at current moment and trying to find solution. @Jean-François Fabre♦ 's answer can't solve my own problem - it freezes arguments values at the moment of initializing Child class and if it change in future your Child class never knows about it.

I made some modifications to fix it:

class Parent(object):
    def __init__(self, id, name):
        self.id = id
        self.name = name
        self.__parent_vars = ['id', 'name']  # make a copy

    def print_values(self):
        res = {}
        for el in self.__parent_vars:
            res[el] = vars(self)[el]
        return res


class Child(Parent):
    def __init__(self, id, name, last_name, age):
        Parent.__init__(self, id, name)
        self.last_name = last_name
        self.age = age

Lets test it:

c = Child(12,"Foo","whatever",34)
res1 = c.print_values()
print(res1)

c.id = 24
res2 = c.print_values()
print(res2)

Output:

{'id': 12, 'name': 'Foo'}
{'id': 24, 'name': 'Foo'}

Now it works as I expected BUT I need to create additioanl variable for it. So if I want to pickle, for example, my class it will also pickle this additional variable that I don't need. Is it possible to do the same actions qwithout creating additional variable?

Upvotes: 0

Jean-François Fabre
Jean-François Fabre

Reputation: 140305

Assuming that you aren't going to add more variables outside __init__, you could freeze the list of variables in the __init__ method of the parent:

def __init__(self, id, name):
    self.id = id
    self.name = name
    self.__parent_vars = dict(vars(self))  # make a copy

then use this dictionary, which has only the variables you defined when you initialized the parent class:

def print_values(self, path):
    print(self.__parent_vars)

testing:

c = Child(12,"Foo","whatever",34)
c.print_vars()

I get:

{'id': 12, 'name': 'Foo'}

Upvotes: 4

Related Questions