Try
method = lambda self, i=i: A.f(self, i)
because otherwise when you call the method i
's value may have changed
Pregunta
in order to automatically generate parameterized tests, I am trying to add methods to a class in by freezing some parameters of an existing method. Here is the piece of Python 3 code
class A:
def f(self, n):
print(n)
params = range(10)
for i in params:
name = 'f{0}'.format(i)
method = lambda self: A.f(self, i)
setattr(A, name, method)
However, the following lines then produce rather disappointing output
a = A()
a.f0()
prints "9" (instead of "0"). I must be doing something wrong, but I can't see what. Can you help ?
Thanks a lot
Edit: this question is indeed a duplicate. I would like to acknowledge the quality of all comments, which go much deeper than the raw answer.
Solución
Try
method = lambda self, i=i: A.f(self, i)
because otherwise when you call the method i
's value may have changed
Otros consejos
The best way to "freeze" parameters in Python is to use functools.partial
. It's roughly equivalent to warwaruk's lambda version, but if you have a function with lots of arguments yet only want to freeze one or two of them (or if you only know certain arguments and don't care about the rest) using partial
is more elegant as you only specify the arguments you want to freeze rather than having to repeat the whole function signature in the lambda.
An example for your program:
class A:
def f(self, n):
print(n)
from functools import partial
for i in range(10): # params
setattr(A, 'f{0}'.format(i), partial(A.f, n=i))
Depending on which version of Python 3 you're using, you may not need to include the 0
in the string format placeholder; starting with 3.1, iirc, it should be automatically substituted.