Reputation: 334
I am reading this piece of code by Alex Martelli mentioned in this question. I understand that sys.modules[__name__]
tells you what module you are currently at, but this line of code at the end of his constant.py
really confuses me. What is the meaning and the point of having such a statement that declares the current module by the end of the file?
# Put in const.py...:
class _const:
class ConstError(TypeError): pass
def __setattr__(self,name,value):
if self.__dict__.has_key(name):
raise self.ConstError, "Can't rebind const(%s)"%name
self.__dict__[name]=value
import sys
sys.modules[__name__]=_const() #this I don't understand
# that's all -- now any client-code can
import const
Basically, my question is that in my opinion this line of code does not do anything; am I understanding it wrong?
Since in Python you don't have to put class definitions in separate files, I argue that I don't really need two modules unless I want to reuse the class "const." Then in this case sys.moldules[__name__]=_const()
is not necessary either... Am I understanding it correctly?
Upvotes: 5
Views: 6619
Reputation: 1466
This is described by Guido van Rossum as a hack that is sometimes recommended:
https://mail.python.org/pipermail/python-ideas/2012-May/014969.html
# foo.py
import sys
class Foo:
def funct1(self, <args>): <code>
def funct2(self, <args>): <code>
sys.modules[__name__] = Foo()
This works because the import machinery is actively enabling this hack, and as its final step pulls the actual module out of sys.modules, after loading it. (This is no accident. The hack was proposed long ago and we decided we liked enough to support it in the import machinery.)
You can easily override
__getattr__
/__getattribute__
/__setattr__
this way. It also makes "subclassing" the module a little easier (although accessing the class to be used as a base class is a little tricky: you'd have to usefoo.__class__
). But of course the kind of API that Greg was griping about would never be implemented this way, so that's fairly useless. And if you were designing a module as an inheritable class right from the start you're much better off just using a class instead of the above hack.
Upvotes: 2
Reputation: 446
I believe it is binding an instance to the module. So when you do import const
, you actually get an instance of the class _const
.
This allows you to call methods on it. Like, for example, the __setattr__
, where in this case it checks that you only bind a variable once.
Upvotes: 2