Is it beneficial to replace a simple Python class with a closure?
Question:
I have the following Python class:
class class A:
"""a class that increments internal variable"""
def __init__(self, x):
self._x = x
def incr(self):
self._x = (self._x + 1) % 10
return self._x
I heard a talk that recommended that such classes with just a constructor and another method really should just be replaced by a function.
So here is my attempt (for Python 2.7):
def incrX(x):
"""closure that increments internal variable"""
d = {'x' : x}
def incr():
d['x'] = (d['x'] + 1) % 10
return d['x']
return incr
Running it:
def test1():
"""testing closure vs. class"""
print 'class...'
a = A(10)
print a.incr()
print a.incr()
print 'closure...'
incr = incrX(10)
print incr()
print incr()
$ python closure.py
running closure experiments
class...
1
2
closure...
1
2
So my question is:
Is there a benefit to replacing a class like A with a closure? Just trying to understand closures better.
Answers:
The real benefit of closures and higher-order functions is that they can represent what the programmer sometimes has in mind. If you as the programmer find that what you have in mind is a piece of code, a function, an instruction on how to compute something (or do something), then you should use a closure for this.
If, on the other hand, what you have in mind is more like an object, a thing (which happens to have some properties, methods, instructions, capabilities, etc.), then you should program it as an object, a class.
In your case I think the best way to implement this is neither 😉 I’d do this with a generator:
def incrX(i):
while True:
i += 1
i %= 10
yield i
incr = incrX(10)
print incr.next()
print incr.next()
With a closure, one can save the self
variable. In particular, when there are many variables to be passed, a closure could be more readable.
class Incr:
"""a class that increments internal variable"""
def __init__(self, i):
self._i = i
def __call__(self):
self._i = (self._i + 1) % 10
return self._i
def incr(i):
"""closure that increments internal variable"""
def incr():
nonlocal i
i = (i + 1) % 10
return i
return incr
print('class...')
a = Incr(10)
print(a()) # 1
print(a()) # 2
print('closure...')
b = incr(10)
print(b()) # 1
print(b()) # 2
closure binds data to functions in a weird way. on the other side, data classes try to separate data from functions. To me both of them are bad design. Never use them. OO(class) is a much more convient and natural way.
I have the following Python class:
class class A:
"""a class that increments internal variable"""
def __init__(self, x):
self._x = x
def incr(self):
self._x = (self._x + 1) % 10
return self._x
I heard a talk that recommended that such classes with just a constructor and another method really should just be replaced by a function.
So here is my attempt (for Python 2.7):
def incrX(x):
"""closure that increments internal variable"""
d = {'x' : x}
def incr():
d['x'] = (d['x'] + 1) % 10
return d['x']
return incr
Running it:
def test1():
"""testing closure vs. class"""
print 'class...'
a = A(10)
print a.incr()
print a.incr()
print 'closure...'
incr = incrX(10)
print incr()
print incr()
$ python closure.py
running closure experiments
class...
1
2
closure...
1
2
So my question is:
Is there a benefit to replacing a class like A with a closure? Just trying to understand closures better.
The real benefit of closures and higher-order functions is that they can represent what the programmer sometimes has in mind. If you as the programmer find that what you have in mind is a piece of code, a function, an instruction on how to compute something (or do something), then you should use a closure for this.
If, on the other hand, what you have in mind is more like an object, a thing (which happens to have some properties, methods, instructions, capabilities, etc.), then you should program it as an object, a class.
In your case I think the best way to implement this is neither 😉 I’d do this with a generator:
def incrX(i):
while True:
i += 1
i %= 10
yield i
incr = incrX(10)
print incr.next()
print incr.next()
With a closure, one can save the self
variable. In particular, when there are many variables to be passed, a closure could be more readable.
class Incr:
"""a class that increments internal variable"""
def __init__(self, i):
self._i = i
def __call__(self):
self._i = (self._i + 1) % 10
return self._i
def incr(i):
"""closure that increments internal variable"""
def incr():
nonlocal i
i = (i + 1) % 10
return i
return incr
print('class...')
a = Incr(10)
print(a()) # 1
print(a()) # 2
print('closure...')
b = incr(10)
print(b()) # 1
print(b()) # 2
closure binds data to functions in a weird way. on the other side, data classes try to separate data from functions. To me both of them are bad design. Never use them. OO(class) is a much more convient and natural way.