Developer
Developer

Reputation: 8400

Python: nested class with static method fails

What is wrong with the following code?

class A:
    def A_M(self): pass
    class B:
        @staticmethod
        def C(): super(B).A_M()

error (Python 2.7.3):

>>> a = A()
>>> a.B.C()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "..x.py", line 36, in C
    def C(): super(B).A_M()
NameError: global name 'B' is not defined

Edit:
the solution was simple as this:

class A:
    def A_M(self): pass
    class B:
        @staticmethod
        def C(): A().A_M()                 #use of A() instead of supper, etc.

Important Note that there is an issue with this solution. If you change the name of super class (i.e. A) then you will have to update all uses inside itself as A :)).

Upvotes: 0

Views: 1859

Answers (3)

b0bz
b0bz

Reputation: 2200

A latecommer, to just encapsulate B in A the easy way is this:

class A:
    def A_M(self):
        return "hi"

    class B:
        @staticmethod
        def C():
            return A().A_M()

a = A()
print a.B().C()

Not sure this is what you need, but the question was still unsolved, so I guessed.

Upvotes: 2

gatto
gatto

Reputation: 2957

class A(object):
    def foo(self):
        print('foo')

    @staticmethod
    def bar():
        print('bar')

    class B(object):
        @staticmethod
        def bar(obj):
            # A.foo is not staticmethod, you can't use A.foo(),
            # you need an instance.
            # You also can't use super here to get A,
            # because B is not subclass of A.
            obj.foo()
            A.foo(obj)  # the same as obj.foo()

            # A.bar is static, you can use it without an object.
            A.bar()

class B(A):
    def foo(self):
        # Again, B.foo shouldn't be a staticmethod, because A.foo isn't.
        super(B, self).foo()

    @staticmethod
    def bar():
        # You have to use super(type, type) if you don't have an instance.
        super(B, B).bar()


a, b = A(), B()

a.B.bar(a)
b.foo()
B.bar()

See this for details on super(B, B).

Upvotes: 3

Eric
Eric

Reputation: 97661

You need to use a fully-qualified name. Also, in python 2.7, you need to use (object), else super(A.B) will give TypeError: must be type, not classobj

class A(object):
    def A_M(self):
        pass

    class B(object):
        @staticmethod
        def C():
            super(A.B).A_M()

Finally, super(A.B) is essentially object here. Did you mean for B to inherit from A? Or were you simply looking for A.A_M()?

Upvotes: 2

Related Questions