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