python:变更类的打印方式
在Python中,是否可以改变类的打印方式?我知道如果我们提供了 __str__
和 __unicode__
方法,就可以改变类的实例被打印的样子。但我想要改变的是整个类的打印方式。
举个例子:
class A(object):
def __str__(self):
return 'hello'
a = A()
print a
这个会打印出 hello
。那么,是否可以改变 print A
的行为?默认情况下,它会打印出类似 <class '__main__.A'>
的内容。
更新:我想我应该解释一下背景。我正在尝试创建MySQL查询,并且有一些类代表数据库表。每个表对应的类都有一个类变量,里面存储着表的名字。所以我想做的是能够把这个类作为参数传给 cursor.execute
,然后在查询中用表名替换掉。
2 个回答
4
用元类来实现这个功能其实很简单。元类就像是类和实例之间的桥梁,类是用来创建实例的,而元类则是用来创建类的。
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
7
是的,可以通过提供一个元类来实现。不过这样做并不好,因为元类不太容易组合,而且会让人感到神秘和困惑。
>>> class A(type):
... def __repr__(self):
... return '<this is not a class!>'
...
>>> class B(object):
... __metaclass__ = A
...
>>> print B
<this is not a class!>
(你也可以改变__str__
,这取决于你想表达的意思)
你更新了你的帖子,提到从一个类生成SQL查询。与其改变str(Class)
,为什么不直接使用Class.__name__
(也就是你定义这个类时用的名字),或者使用Class.table_name
(也就是你为每个类定义的某个属性)呢?如果你能传入类,并让它们自动作为表名使用,而不是像<class 'foo.x'>
这样的形式,这可能会让将来阅读你代码的人感到非常困惑,因为从上下文中并不清楚这应该是可行的。读者必须记住涉及了元类的技巧(这是一种相对少见的情况,虽然在ORM中并不少见!),并且要理解这个元类技巧的作用。相比之下,直接传入Class.table_name
而不是Class
,就能让人很清楚地明白发生了什么。