Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can a python module have a __repr__?

Tags:

python

module

Can a python module have a __repr__? The idea would be to do something like:

import mymodule
print mymodule

EDIT: precision: I mean a user-defined repr!

like image 963
static_rtti Avatar asked Nov 12 '09 21:11

static_rtti


2 Answers

Short answer: basically the answer is no.

But can't you find the functionality you are looking for using docstrings?

testmodule.py
""" my module test does x and y
"""
class myclass(object):
    ...
test.py
import testmodule
print testmodule.__doc__

Long answer:

You can define your own __repr__ on a module level (just provide def __repr__(...) but then you'd have to do:

import mymodule
print mymodule.__repr__() 

to get the functionality you want.

Have a look at the following python shell session:

>>> import sys                 # we import the module
>>> sys.__repr__()               # works as usual
"<module 'sys' (built-in)>"
>>> sys.__dict__['__repr__']     # but it's not in the modules __dict__ ?
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: '__repr__'
>>> sys.__class__.__dict__['__repr__'] # __repr__ is provided on the module type as a slot wrapper
<slot wrapper '__repr__' of 'module' objects>
>>> sys.__class__.__dict__['__repr__'](sys) # which we should feed an instance of the module type
"<module 'sys' (built-in)>"

So I believe the problem lies within these slot wrapper objects which (from what can be read at the link) have the result of bypassing the usual 'python' way of looking up item attributes.

For these class methods CPython returns C pointers to the corresponding methods on these objects (which then get wrapped in the slot wrapper objects to be callable from the python-side).

like image 53
ChristopheD Avatar answered Nov 08 '22 10:11

ChristopheD


You can achieve this effect--if you're willing to turn to the Dark Side of the Force.

Add this to mymodule.py:

import sys

class MyReprModule(mymodule.__class__):
  def __init__(self, other):
    for attr in dir(other):
      setattr(self, attr, getattr(other, attr))

  def __repr__(self):
    return 'ABCDEFGHIJKLMNOQ'

# THIS LINE MUST BE THE LAST LINE IN YOUR MODULE
sys.modules[__name__] = MyReprModule(sys.modules[__name__])

Lo and behold:

>>> import mymodule
>>> print mymodule
ABCDEFGHIJKLMNOQ

I dimly remember, in previous attempts at similarly evil hacks, having trouble setting special attributes like __class__. I didn't have that trouble when testing this. If you run into that problem, just catch the exception and skip that attribute.

like image 24
Larry Hastings Avatar answered Nov 08 '22 12:11

Larry Hastings