當然,你可以(儘管可能不應該)只使用type
:
In [1]: class Button:
...: def callback(self):
...: print('Hello')
...:
In [2]: button = type('', (Button,), {'callback': lambda self: print('World')})()
In [3]: button.callback()
World
您可能希望定義表達式之外的功能,以便能夠避免代碼高爾夫球它:
In [5]: def callback(self):
...: print('World')
...: button = type('', (Button,), {'callback': callback})()
...:
In [6]: button.callback()
World
這正是Java正在做的事情,但它更明確地做了這些,因此使用了更繁瑣的語法。事實上,在Python中,你可以定義局部類:
In [7]: def function():
...: class MyButton(Button):
...: def callback(self):
...: print('Hello, from a local class!')
...: return MyButton()
...:
In [8]: button = function()
In [9]: button.callback()
Hello, from a local class!
相對於Java的唯一的區別是,你必須向類提供一個名稱,並用它來創建一個實例。使用裝飾你能避免這最後一步:
def auto_instantiator(*args, **kwargs):
def decorator(cls):
return cls(*args, **kwargs)
return decorator
用作:
In [2]: class Button:
...: def callback(self):
...: print('Button')
...:
In [3]: @auto_instantiator() # here args that should be passed to __init__
...: class button(Button):
...: def callback(self):
...: print('New Button')
...: # no need for button = button(...)
In [4]: button.callback() # button is an *instance* of the button class
New Button
但是,這取決於你將如何使用該方法,我建議兩種不同的方式來處理問題:
其實所有按鈕的動作都是一樣的,除了一些數據。在這種情況下,它可能會更好只是創建一個實例屬性(或屬性)來保存數據,並更改數據,而不是方法:
我的意思是這樣的:
class Greeter:
def __init__(self, name):
self.name = name
def greet(self):
print('Hello, {.name}'.format(self))
你可以只設置實例屬性回調你想要的:
button.callback = new_callback
一般情況下,我得到的感覺是Python的方式做,這是創建一個按鈕基類,然後只是重寫東東方法d爲每個單獨的按鈕覆蓋...(但是,我不是Java程序員,所以我可能會錯誤地解釋你想做什麼......) – mgilson 2015-02-07 17:35:19
關於Java方法,我認爲它確實創建了一個類,只是它的範圍受到了限制。在Python中,你可以在函數內部創建類,這很類似。請注意,我實際上是指類,而不是實例! – 2015-02-07 17:38:35
好吧,它們並不完全等價,在Python中,函數內的類會爲每次運行創建一個全新的類對象,而在Java中它更像是一個Python閉包。 – 2015-02-07 17:43:22