I'm pretty sure that you can't do what you want to do if you import like from hardcoded_values import *
.
What you want to do is to set foo
to some function, and then apply the property
decorator (or equivalent) so that you can call foo as foo
rather than foo()
. You cannot apply the property decorator to modules for reasons detailed here: Why Is The property Decorator Only Defined For Classes?
Now, if you were to import hardcoded_values
then I think there is a way to do what you want to hardcoded_values.foo
. I have a pretty good feeling that what I am about to describe is a BAD IDEA that should never be used, but I think it is interesting.
BAD IDEA???
So say you wanted to replace a constant like os.EX_USAGE
which on my system is 64
with some function, and then call it as os.EX_USAGE
rather than os.EX_USAGE()
. We need to be able to use the property
decorator, but for that we need a type other than module
.
So what can be done is to create a new type on the fly and dump in the __dict__
of a module with a type factory function that takes a module as an argument:
def module_class_factory(module):
ModuleClass = type('ModuleClass' + module.__name__,
(object,), module.__dict__)
return ModuleClass
Now I will import os:
>>> import os
>>> os.EX_USAGE
64
>>> os.getcwd()
'/Users/Eric'
Now I will make a class OsClass
, and bind the name os
to an instance of this class:
>>> OsClass = module_class_factory(os)
>>> os = OsClass()
>>> os.EX_USAGE
64
>>> os.getcwd()
'/Users/Eric'
Everything still seems to work. Now define a function to replace os.EX_USAGE
, noting that it will need to take a dummy self
argument:
>>> def foo(self):
... return 42
...
...and bind the class attribute OsClass.EX_USAGE
to the function:
>>> OsClass.EX_USAGE = foo
>>> os.EX_USAGE()
42
It works when called by the os
object! Now just apply the property decorator:
>>> OsClass.EX_USAGE = property(OsClass.EX_USAGE)
>>> os.EX_USAGE
42
now the constant defined in the module has been transparently replaced by a function call.