1

Is it possible to make a module callable with parameters?

I am trying to make a callable module on Python, following the question and its answers Callable modules, like so:

foo.py

import sys

class foo(object):
  def __call__(self):
    return 'callable'

sys.modules[__name__] = foo()

then I call it:

import foo

print(foo()) # 'callable'

but my objective is to pass a parameter in the callable module:

print(foo('parameter'))

Any ideas how can I accomplish that?

Abraham
  • 8,525
  • 5
  • 47
  • 53

1 Answers1

0

There's nothing special about the class you created (it's not even a ModuleType subclass), so there's nothing special about its __call__ method. If you want to call it with arguments, just add parameters to the __call__ definition:

import sys

class foo(object):
  def __call__(self, x):
    return f'callable, and called with {x}'

sys.modules[__name__] = foo()

And now, you can pass it an argument, exactly like any other callable object:

import foo

print(foo('hello'))

And the output is:

callable, and called with hello

From the comments, you tried to do this:

def __call__(a, self):
    return a

But, like all methods in Python, __call__ wants self to come first. It doesn't care about the names (unless you call it with keyword arguments), just the order: the first parameter gets the receiver (the foo in foo('hello')), even if it you called that parameter a, and the second parameter gets the first normal argument (the 'hello'), even if you called that parameter self.

So, you're passing the module foo as the first parameter, a, and you return a, so it returns foo.

Which is why you got this:

<sta.foo object at 0x10faee6a0>

That isn't an error, that's the perfectly valid output that you get when you print out an instance of a class that doesn't define __repr__ or __str__.

abarnert
  • 354,177
  • 51
  • 601
  • 671
  • This does not always work though sadly. If you do from foo import * then foo('test') will throw an error, 'foo is not defined'. – ckloan Jun 30 '20 at 03:29