0

I denfind a class inside a function, I found the function argument is available for class even I doesn't initialize the class with function arguments.

my code like

def func1(p1,p2):
    class test1(object):
        def __init__(self, arg1):
            self.v1 = p1
            self.v2 = p2
            self.v3 = arg1
    return test1 
testclass = func1(2,13)
testobj = testclass(234)
print(testobj.v1)
print(testobj.v2)
print(testobj.v3)

Print is fine , can someone explain why.

xin king
  • 21
  • 6

1 Answers1

2

Function parameters are converted to local variables when the function is called. When you define test1.__init__, arg1 is a local variable initialized from the parameter list. p1 and p2 are free variables - they are expected to be resolved in the outer scope at runtime. test1 is compiled as an inner class to func1 which defines these as local variables. So, these variables are resolved to local variables in func1. But these local variables only exist when func1 is called, so how could you possibly use test1 outside of the function?

Python recognizes this odd situation and creates a closure whenever func1 is called. test1.__init__ knows that p1 and p2 are to be referenced in the closure. And func1 knows to put the p1 and p2 values in the closure then create a new version of the test1 class whenever it is called.

As a result, each time you call func1, you get a new special case of class test1 which has been parameterized with the p1 and p2 values you used to call func1. This association is setup when func1 returns and lasts for the lifetime of the class object returned by func1. Each call to func1 gives you a different class.

testclass = func1(2,13)    # create class <locals>.test1
                           #     and the closure (2, 13)
testobj = testclass(234)   # instantiate the class which assigns
                           #    self.v1 <-- 234 from the parameter list
                           #    self.v2 <-- 2 from the closure
                           #    self.v3 <-- 13 from the closure
tdelaney
  • 73,364
  • 6
  • 83
  • 116