python:变更类的打印方式

9 投票
2 回答
866 浏览
提问于 2025-04-16 15:43

在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,就能让人很清楚地明白发生了什么。

撰写回答