0

Getting below Attribute error while running below code. Class member function is accessed using self still it is giving error.

class A:
    def __init__(self):
        self.a=1
    def f1(self):
        self.b=2
        def f2(self):
            self.c=3
            print(self.a,self.b,self.c)
        self.f2()

model = A()
model.f1()

Error:

AttributeError: 'A' object has no attribute 'f2'
3
  • What's confusing? The class doesn't have an f2 function. Commented Dec 18, 2017 at 18:37
  • You defined f2() within f1(), so the class itself does not know what f2() is. Commented Dec 18, 2017 at 18:38
  • Why do you expect self.f2() to be defined??? Commented Dec 18, 2017 at 18:57

3 Answers 3

3

A does not have an attribute f2, but it does have an attribute f1 that calls a function f2. f2 is not an instance attribute.

In this case c is no longer an instance attribute, or data attribute, it is now just a local variable. This may or may not be what you were going for.

class D:
    def __init__(self):
        self.a = 1

    def f1(self):
        # Instance attribute declared outside of __init__
        self.b = 2

        def f2():
            c = 3
            print(self.a, self.b, c)
        f2()

Depending on your development environment you may or may not get a warning about instance attributes being declare outside of the __init__ function. It isn't necessary that you declare them this way, however, it improves readability.

class B:
    def __init__(self):
        self.a = 1
        self.b = 2
        self.c = 3

    def f1(self):
        def f2():
            print(self.a, self.b, self.c)
        f2()

This next block is slightly more explicit in what it says about the intent of the code.

class A:
    def __init__(self):
        self.a = 1
        self.b = 2
        self.c = 3

    def f1(self):
        def f2():
            return '{} {} {}'.format(self.a, self.b, self.c)
        return f2()

Perhaps you want f2() to be called using method attributes of the self argument in which case:

class A2:
    def __init__(self):
        self.a = 1
        self.b = 2
        self.c = 3

    def f2(self):
        print(self.a, self.b, self.c)

    def f1(self):
        """Do something that requires calling the self.f2()
        print function.
        """
        self.f2()
Sign up to request clarification or add additional context in comments.

Comments

1

You do not need self when calling the nested function and nor does it need to be contained in the function signature:

class A:
   def __init__(self):
     self.a=1
   def f1(self):
     self.b=2
     def f2():
        c=3
        print(self.a,self.b, c)
     f2()

model = A()
model.f1()

Output:

1, 2, 3

Comments

0

Its not clear to me that you actually need to define a function within a method just to call it.

So, your code could just as easily be this:

class A:
    def __init__(self):
        self.a = 1

    def f1(self):
        self.b = 2
        self.f2()

    def f2(self):
        self.c = 3
        print(self.a, self.b, self.c)

model = A()
model.f1()

Output:

1 2 3

Comments

Your Answer

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