2011-04-14 121 views
7

是否有可能在python中更改爲類打印的內容。我知道如果我們提供__str____unicode__方法,我們可以改變打印類的實例的方式。但我想一類python:更改類的打印

如這樣做:

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

a = A() 
print a 

將打印hello。是否有可能改變print A的行爲,在默認情況下打印像<class '__main__.A'>

更新:我想我也可以解釋的上下文。我正在嘗試創建MySQL查詢,並且我有表示表的類。每個表類都有一個包含表名的類變量。所以我想要做的是能夠將Class作爲參數傳遞給cursor.execute,並在查詢中替換表名。

回答

5

是的,通過提供一個metaclass。這是一個糟糕的主意,因爲元類的構成不是很好,而且很神奇而且令人困惑。

>>> 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(即您爲每個類定義的某個類屬性)?能夠傳入類並讓它們自動地以非012.的形式工作的表名可能會讓未來的代碼讀者感到困惑,因爲不清楚這是否適用於上下文。讀者必須記住,metaclass入侵(一個比較罕見的事情,雖然不在ORM中),而元類攻擊卻做了什麼。相比之下,僅僅通過Class.table_name而不是Class使得非常明顯的發生了什麼。

+0

「元類不構成很好,它是神奇的和令人困惑的」你能詳細說一下 – z33m 2011-04-14 07:18:33

+3

@zeem Re:構成,使用兩個不同的元類需要你創建一個新的元類繼承他們兩個,這可能會如果他們不打算繼承,就不會很好地工作。作爲一般規則,類,特別是元類,並不意味着從多個繼承,並且這可以並且將會炸燬。回覆:神奇/令人困惑,基本問題是人們希望'repr(SomeClass)'看起來像一個類的repr,如果你改變它,那就打破了這個期望。所以人們可能會看到一個班級,甚至不知道這是一個班級。 – 2011-04-14 07:35:12

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