Just working through learning python and started to look at nested/factory functions (simple example):
def maker(N):
def action(X):
return X * N
return action
Are there any advantages of factory functions over creating a class? performance? memory? clean up?
Factories are much more flexible than either constructor functions or classes, and they don't lead people down the wrong path by tempting them with the `extends` keyword and deep inheritance hierarchies. There are many safer code reuse mechanisms you should favor over class inheritance, including functions and modules.
Factory method is a creational design pattern which solves the problem of creating product objects without specifying their concrete classes. The Factory Method defines a method, which should be used for creating objects instead of using a direct constructor call ( new operator).
A constructor returns an instance of the class you call it on. A factory function can return anything. You would use a factory function when you need to return arbitrary values or when a class has a large setup process.
Factory Method is a creational design pattern used to create concrete implementations of a common interface. It separates the process of creating an object from the code that depends on the interface of the object. For example, an application requires an object with a specific interface to perform its tasks.
What I like most about nested functions is that it is less verbose than classes. The equivalent class definition to your maker function is:
class clsmaker(object):
def __init__(self, N):
self.N = N
def __call__(self, X):
return X * self.N
That doesn't seem so bad until you start adding more arguments to the constructor. Then doing it the class way takes an extra line for each argument, while the function just gets the extra args.
It turns out that there is a speed advantage to the nested functions as well:
>>> T1 = timeit.Timer('maker(3)(4)', 'from __main__ import maker')
>>> T1.timeit()
1.2818338871002197
>>> T2 = timeit.Timer('clsmaker(3)(4)', 'from __main__ import clsmaker')
>>> T2.timeit()
2.2137160301208496
This may be due to there being fewer opcodes involved in the nested functions version:
>>> dis(clsmaker.__call__)
5 0 LOAD_FAST 1 (X)
3 LOAD_FAST 0 (self)
6 LOAD_ATTR 0 (N)
9 BINARY_MULTIPLY
10 RETURN_VALUE
>>> act = maker(3)
>>> dis(act)
3 0 LOAD_FAST 0 (X)
3 LOAD_DEREF 0 (N)
6 BINARY_MULTIPLY
7 RETURN_VALUE
Comparing a function factory to a class is comparing apples and oranges. Use a class if you have a cohesive collection of data and functions, together called an object. Use a function factory if you need a function, and want to parameterize its creation.
Your choice of the two techniques should depend on the meaning of the code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With