Generate a new object each time a name is imported

Terry Reedy tjreedy at udel.edu
Sun Aug 2 14:07:44 EDT 2009


Peter Otten wrote:
> Steven D'Aprano wrote:

>> I'm looking for a way to hide the generation of objects from the caller,
>> so I could do something like this:
>>
>> from Module import factory() as a  # a == "Object #1"
>> from Module import factory() as b  # b == "Object #2"
>>
>> except of course that syntax is illegal.
> 
> How about

For newbies who do not get how the following works, but would like to 
know, I am adding some explanation.

>>>> class A(object):
> ...     def __init__(self):
> ...             self._n = 0
> ...     @property
> ...     def a(self):
> ...             try:
> ...                     return self._n
> ...             finally:
> ...                     self._n += 1

The @property decorator turns the 'a' function into the hidden getter 
function for what looks to the outside world like a simple instance 
attribute named 'a'.

>>>> import sys
>>>> sys.modules["yadda"] = A()

sys.modules is a system namespace that normally associates names with 
modules. It is used by import statements to find existing modules. 
However, there is no requirement that the associated object actually be 
a module. A module is simply a collection of objects accessed as 
attributes. One can get and set attributes of a module, and but hardly 
anyhing else. Other attribute collection objects will do as well as far 
as imports are concerned. 'If it quack like a duck (module in this case)...'

The above sets the 'module' to an *instance* of class A.

>>>> from yadda import a

This looks for the 'module' named 'yadda'. It finds one - the instance 
of A. It then requests attribute 'a' (of that instance). That request is 
routed to the getter function.

This import statement could be in any module, not just the one that set 
A() as a module surrogate.

>>>> from yadda import a as b
>>>> a, b
> (0, 1)

As Peter mentioned in his followup, module surrogates were intended for 
lazy imports of expensive-to-compute attributes that might never be 
needed, so their creation could be delayed to whenever needed, if ever.

Tricks like the above are not recommended for normal usage, but do 
illstrate some aspects of the language.

Terry Jan Reedy




More information about the Python-list mailing list