0

How can I assign a variable from an outer class to the inner? Here is my best attempt:

in [1]: class one:
   ...:     x = 1
   ...:     class two:
   ...:         y = x
   ...:         
--------------------------------------------------------------------------- 
NameError: name 'x' is not defined

I am confused as to why this doesn't work, but Python has no problem with this syntax:

In [1]: x = 1
In [2]: class one:
   ...:     y = x
   ...:     class two:
   ...:         z = x
   ...:         

In [3]: one.two.z
Out[3]: 1
6
  • How can I rephrase this question? Edit: Thanks Jeremy Banks I now see this is an outer class. Commented Jan 28, 2016 at 23:14
  • 3
    Why are you even putting one class inside another? There's almost never a reason to do that in Python. Commented Jan 28, 2016 at 23:16
  • 1
    Related: Nested Python class needs to access variable in enclosing class Commented Jan 28, 2016 at 23:16
  • 1
    @kilojoules I'm not certain if "outer class" is a formal/standard term for this, but it's one I've seen used elsewhere and is hopefully a bit clearer. I always get Python's behaviour in this context mixed up; it's not very obvious. Commented Jan 28, 2016 at 23:17
  • 1
    In the second example, 'x' is not defined within the scope of y. In the first example, x is defined in the global scope. Commented Jan 28, 2016 at 23:26

2 Answers 2

0

What you are doing makes no sense to me, anyway, you can access outer class's instance variable by passing its instance into inner class. Nested classes are not recommended. You can use Inheritance to achieve this.

class Outer:
    def __init__(self):
        self._x = 1

    def create_inner(self):
        """passes outer class instance into Inner"""
        return Outer.Inner(self)

    class Inner:
        def __init__(self, outer):
            self._outer = outer
            self._y = self._outer._x

        def print_y(self):
            print self._y


outer = Outer()
inner = outer.create_inner()
inner.print_y()

Output:

1
Sign up to request clarification or add additional context in comments.

Comments

-1

When a class definition is encountered Python will execute the body without second thought.

First, it will execute class one, while executing the body (and before actually creating the class), it will encounter class two so it will execute that.

Inside class two it will see a reference to one which still does not exist, hence a NameError will be raised.

One simple way to see the difference in the way Python treats classes/functions is by wrapping the second class definition inside a function. Since Python only compiles functions and doesn't execute them, class one is going to get created:

class one:
    x = 1
    def wrap():
        class two:
            y = one.x
        one.two = two

Now one exists as a class. If you execute one.wrap the second class definition is going to get executed, the one class is going to be found and then, just to follow along with your original example; I set the class two as an attribute of one to get the same effect you were going for.

As a result, name resolution works fine and class two now has an attribute of class one:

one.wrap()

one.two.y
Out[22]: 1

Do Note: Moving the second class outside of the first class definition works too, but that's besides the point.

2 Comments

Great! One small note to others - it should be def wrap(self):. otherwise it will throw a number of arguments error.
@kilojoules The TypeError is raised if you instantiate. If not you should be good to go. Either way, this example with the nested class in the def was not meant as something that you should use but more so in order to illustrate how Python executes classes vs compiles functions.

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.