tags:

views:

99

answers:

3

Suppose one decided (yes, this is horrible) to create handle input in the following manner: A user types in a command on the python console after importing your class, the command is actually a class name, the class name's __str__ function is actually a function with side effects (e.g. the command is "north" and the function changes some global variables and then returns text describing your current location). Obviously this is a stupid thing to do, but how would you do it (if possible)?

Note that the basic question is how to define the __str__ method for a class without creating an instance of the class, otherwise it would be simple (but still just as crazy:

class ff:
    def __str__(self):
        #do fun side effects
        return "fun text string"

ginst = ff()

>>ginst
A: 

in console you're getting representation of your object, which __repr__ is responsible for. __str__ used for printing:

>>> class A:
    def __str__(self):
     return 'spam'


>>> A()
<__main__.A object at 0x0107E3D0>
>>> print(A())
spam

>>> class B:
    def __repr__(self):
     return 'ham'


>>> B()
ham
>>> print(B())
ham

>>> class C:
    def __str__(self):
     return 'spam'
    def __repr__(self):
     return 'ham'


>>> C()
ham
>>> print(C())
spam
SilentGhost
You are still instantiating the class, though. That's not what was asked.
shylent
A: 

You could use instances of a class rather than classes themselves. Something like

class MagicConsole(object):
    def __init__(self, f):
        self.__f = f

    def __repr__(self):
        return self.__f()

north = MagicConsole(some_function_for_north)
south = MagicConsole(some_function_for_south)
# etc
Corey Porter
+4  A: 

What you are looking for is the metaclass

class Magic(type):
    def __str__(self):
        return 'Something crazy'
    def __repr__(self):
        return 'Another craziness'

class Foo(object):
    __metaclass__ = Magic

>>> print Foo
Something crazy
>>> Foo
Another craziness
Nadia Alramli
in py3k you'd need to pass `metaclass` as a keyword: `class Bar(metaclass=Magic): pass` for this method to work.
SilentGhost
@SilentGhost, thanks for the note
Nadia Alramli
Yep, that's what I was thinking of.
Brian