Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python: change printing of class [duplicate]

Is it possible in python to change what is printed for classes. I know that if we provide __str__ __unicode__ methods, we can change the way instances of a class are printed. But i want to do this for a class

Eg:

class A(object):
    def __str__(self):
        return 'hello'

a = A()
print a

will print hello. Is it possible to change the behaviour of print A which by default prints something like <class '__main__.A'>

Update: I guess i might as well explain the context. I am trying to create MySQL queries and i have classes representing tables. Each of these table-classes have a class variable containing the table name. So what i want to do is to be able to pass the Class as parameter to cursor.execute and have the tablenames substituted in the query.

like image 800
z33m Avatar asked Apr 14 '11 07:04

z33m


2 Answers

Yes, by providing a metaclass. This is a bad idea because metaclasses don't compose very well, and it's magical and confusing.

>>> class A(type):
...     def __repr__(self):
...             return '<this is not a class!>'
...
>>> class B(object):
...     __metaclass__ = A
...
>>> print B
<this is not a class!>

(you can change __str__ as well, it depends on the semantics of what this is)


You updated your post to talk about generating SQL queries from a class. Instead of changing str(Class), why not instead use Class.__name__ (i.e. the name you defined it with), or perhaps Class.table_name (i.e. some class attribute you define for each class)? Being able to pass in classes and have them automagically work as table names that aren't of the form <class 'foo.x'> is potentially very confusing to future readers of your code, because it's not clear that this should work from context. The reader must remember that metaclass hacks were involved (a relatively rare thing, although not in ORMs!) and what the metaclass hack did. In contrast, just passing Class.table_name instead of Class makes it very obvious what is going on.

like image 55
Devin Jeanpierre Avatar answered Oct 16 '22 05:10

Devin Jeanpierre


Easy enough with a metaclass. A metaclass is to the class, what the class is to the instance

class A_meta(type):
    def __str__(cls):
        return 'foobar'


class A(object):
    __metaclass__ = A_meta
    def __str__(self):
        return 'hello'

a = A()
print a
print A
like image 41
John La Rooy Avatar answered Oct 16 '22 05:10

John La Rooy