0

Let's assume I have two classes:

#!/usr/bin/env python

class First():

        glob = 'Global data'

        def __init__(self, arg1, arg2):
                self.arg1 = arg1
                self.arg2 = arg2
                print (arg1, arg2)

class Second(First):
        def __init__(self):
                print (self.glob)

And they are called from script as:

#!/usr/bin/env python

import classes

data1 = 'First data part'
data2 = 'Second data part'

inst1 = classes.First(data1, data2)
inst2 = classes.Second()

This works, OK:

$ ./script.py
('First data part', 'Second data part')
Global data

I want to make arg1 and arg2 in First class something 'global', and use then it in Second:

class Second(First):
        def __init__(self):
                print (self.glob, self.arg1, self.arg2)

How I can achieve it?

2
  • You are confusing instance data with class data. The attributes you set in the __init__ of First are per-instance attributes; instances of another class (even a subclass) won't see those. What values would instances of Second ever have for those attributes? Commented Sep 11, 2014 at 13:56
  • 1
    You will have to call First.__init__ yourself (since you are overriding it in the child class), possibly via the super function. After this super call, you will have access to those attributes. Commented Sep 11, 2014 at 13:58

3 Answers 3

1
class First(object):

    glob = 'Global data'

    def __init__(self, arg1, arg2):
        self.arg1 = arg1
        self.arg2 = arg2
        #print (arg1, arg2)

class Second(First):
    def __init__(self, *args):
        super(Second, self).__init__(*args)
        print (self.glob, self.arg1, self.arg2)

data1 = 'First data part'
data2 = 'Second data part'

inst1 = First(data1, data2)
inst2 = Second(data1, data2)
Sign up to request clarification or add additional context in comments.

5 Comments

I think the OP question was python3 (just a guess)
super - seems what I need... Thanks, don't know about it.
@setevoy if you want to use fields of the parent class you need to call parent __init__
@Andrey yep, I understood... Tried do same with direct call First(data1, data2) inside __init__ of Second :-)
Btw - it also works: First.__init__(self, *args); but seems this is incorrect way...
1

You can use unpacking in your First class __init__() method:

class First:

    def __init__(self, *args):
        for data in args:
            print(data)

# in your child class, you need to call First.__init__(), via super()

class Second(First):

    def __init__(self, *args):
        super(Second, self).__init__(*args)  # pass args to First.__init__()

Usage:

import classes

i = Second("data", "data1", "data2", "data3")

Using unpacking allow your class to accept any number of arguments and will make writing subclasses faster and easier. Depending on your use case, it will sometimes better to use dictionnary unpacking, especially if you want named arguments:

class First:

    def __init__(self, **kwargs): # note the double wildcards here
        print(kwargs.get('data1'))
        print(kwargs.get('data2'))

class Second(First):

    def __init__(self, **kwargs):
        super(Second, self).__init__(**kwargs) 

# usage

i = Second(data1="something", data2="something else", another_arg="Yahoo")

Comments

1

The init of First is overloaded by Second, call the one of your parent class from your Second class

class Second(First):
    def __init__(self):
        super(Second, self).__init__("argument1", "argument2")
        print (self.glob, self.arg1, self.arg2)

In python3 it is like this:

class Second(First):
    def __init__(self):
        super().__init__("argument1", "argument2")
        print (self.glob, self.arg1, self.arg2)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.