Defining a local class in your case seems useless. I'd do that if I did want to return it. There some disadvantages when defining local classes:
- Readability: either the class is really trivial or the function inevitably grows quite long and its logic is lost in the class declaration. Also you have an extra level of indentation which might hurt readability if you have some nested loops somewhere
- Performance: the class will be re-costructed at every function call. This usually wont take a huge amount of time, but it will cost a bit. If the function you are running is fast this cost may be significant.
There are also some advantages of defining a local class:
- Locality: you are generally pretty sure that the class wont be used outside the function, in ways you didn't expect
- Performance: looking up a local variable is significantly faster then looking up a global variable. If you create a big number of instances this might improve performance with respect to using a global class. However it's really really easy to counter this advantage via default arguments/local variables.
My suggestion would be to simply define the class globally and, if it should be private, use a name that starts with an underscore, like _MyClass
, since this is the convention used to denote private items.
Some timings to give an idea of the changes in performance:
In [1]: class _Out(object):
...: def test(self):
...: for _ in range(10):
...: pass
...:
In [2]: def function_out(n):
...: for _ in range(n):
...: _Out().test()
...:
In [3]: def function_in(n):
...: class Inner(object):
...: def test(self):
...: for _ in range(10):
...: pass
...: for _ in range(n):
...: Inner().test()
...:
In [4]: def function_mixed(n, cls=_Out):
...: # use of default to access the global class via local variable
...: for _ in range(n):
...: cls().test()
...:
In [5]: %timeit function_out(1000)
1000 loops, best of 3: 602 us per loop
In [6]: %timeit function_in(1000)
1000 loops, best of 3: 621 us per loop
In [7]: %timeit function_mixed(1000)
1000 loops, best of 3: 590 us per loop
In [8]: %timeit function_out(100000)
10 loops, best of 3: 59.9 ms per loop
In [9]: %timeit function_in(100000)
10 loops, best of 3: 60.2 ms per loop
In [10]: %timeit function_mixed(100000)
10 loops, best of 3: 58.4 ms per loop
In [11]: %timeit function_out(10)
100000 loops, best of 3: 6.52 us per loop
In [12]: %timeit function_in(10)
10000 loops, best of 3: 57.8 us per loop
In [13]: %timeit function_mixed(10)
100000 loops, best of 3: 6.33 us per loop
Note how with a big number of iterations function_in
and function_out
run in about the same time, while with small number of iterations function_in
is about 10 times slower.