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()
f2function.f2()withinf1(), so the class itself does not know whatf2()is.self.f2()to be defined???