Function To Make Functions Callable Doesn't Work Properly
Solution 1:
I believe that's what you're looking for:
classCallable(object):
def__init__(self, func, *args, **kwds):
self.func = func
self.args = args
self.kwds = kwds
def__call__(self, *args, **kwds):
return self.func(*self.args, *args, **self.kwds, **kwds)
def__str__(self):
return self.func.__name
You need to unpack it with the *
operator, and **
for keyword arguments. That way you pass your variables and the function's call variables.
UPDATE:
For python versions older than 3.5, this will work:
classCallable(object):
def__init__(self, func, *args, **kwds):
self.func = func
self.args = args
self.kwds = kwds
def__call__(self, *args, **kwds):
args = self.args + args
kwargs = kwds.copy()
kwargs.update(self.kwds)
return self.func(*args, **kwargs)
def__str__(self):
return self.func.__name
Using this solution, you will first give the variables acquired by the __init__
then the variables passed to the __call__
.
Solution 2:
Your class is used to provide additional context to tkinter callbacks so the callback can actually do something useful. You almost have it right except that you need to unpack the original args and kwds when calling the function. Also, don't include any args in __call__
because you don't accept any.
classCallable(object):
def__init__(self, func, *args, **kwds):
self.func = func
self.args = args
self.kwds = kwds
def__call__(self):
return self.func(*self.args, **self.kwargs)
def__str__(self):
return self.func.__name
defsome_callback(a, b, c=None):
print(a,b,c)
Button(text="Do not press",
command=Callable(some_callback, 1, 2, 3))
This can also be done without a class, using lambdas instead
defsome_callback(a, b, c=None):
print(a,b,c)
Button(text="Do not press",
command=lambda: some_callback(1, 2, 3))
Solution 3:
Please consider using the following class. It allows you to specify positional arguments and keyword arguments at the time of either instance creation or instance invocation (creating a new instance or calling it). Since it is ambiguous what would be meant if either types of arguments were specified at both times, the class refuses to guess what order or priorities were intended and raises a RuntimeError
to prevent undefined behavior. Also, the __str__
method should still work if your function or other callable object does not have a __name__
attribute.
classCallable:
def__init__(self, function, *args, **kwargs):
self.__function, self.__args, self.__kwargs = function, args, kwargs
def__call__(self, *args, **kwargs):
if (args or kwargs) and (self.__args or self.__kwargs):
raise RuntimeError('multiple args and kwargs are not supported')
if args or kwargs:
return self.__function(*args, **kwargs)
return self.__function(*self.__args, **self.__kwargs)
def__str__(self):
returngetattr(self.__function, '__name__', 'function')
You might also want to take a look at functools.partial
for a well-defined object with very similar behavior. You may be able to avoid defining your own Callable
class and use the functools
module instead. That way, there is less code that you have to manage in you project.
Post a Comment for "Function To Make Functions Callable Doesn't Work Properly"