我曾經在scheme中編程:在scheme(一種功能風格)中,函式就是值。你可以將一個函式附加到一個“結構”——相當于python中一個類的方案——你能用python類做類似的事情嗎?
uj5u.com熱心網友回復:
class MyClass:
def my_method(self):
print("Hello world!")
或者
通過使用my_object.my_method = my_function或MyClass.my_method = my_function您可以動態添加它。但這是不鼓勵的,因為它使代碼更難理解。
編輯:要獲取接收selfarg的系結方法,您需要將其添加到類中。這也反映在現有實體上。如果直接將方法添加到實體中,則self呼叫時不會收到。
uj5u.com熱心網友回復:
答案是肯定的:函式是 Python 中的一等值,您可以將這些動態附加到類或類實體以創建方法。在類的情況下,這是微不足道的,但在實體的情況下,這需要一些設定。
為了說明差異,請考慮以下代碼:
class Hello:
def say_hello(self):
print("Hello")
print(type(Hello.say_hello)) # <class 'function'>
print(type(Hello().say_hello)) # <class 'method'>
可以看到,對于同一個方法,從類中參考時為函式型別,從實體中參考時為方法型別。(此外,函式和方法本身也是類;它一直是海龜。)
要動態地向類添加方法,使用常規函式就足夠了。例如:
def say_hello(self):
print(f"Hello, {self.name}!")
class Greeter:
def __init__(self, name):
self.name = name
Greeter.greet = say_hello
Greeter("Sir Robin").greet() # Prints "Hello, Sir Robin!"
但是,實體上的方法系結到實體;這意味著當您呼叫 時instance.method(),Python 會self自動為該方法提供引數。對于普通類,Python 自己處理系結,但是當您動態添加方法時不會發生這種情況。例如,此代碼將導致錯誤:
def say_hello(self):
print(f"Hello, {self.name}!")
class Greeter:
def __init__(self, name):
self.name = name
greeter = Greeter("Sir Robin")
greeter.greet = say_hello
greeter.greet() # TypeError: say_hello() missing 1 required positional argument: 'self'
相反,您必須自己系結方法。這可以使用型別庫中的MethodType來完成。
import types
def say_hello(self):
print(f"Hello, {self.name}!")
class Greeter:
def __init__(self, name):
self.name = name
greeter = Greeter("Sir Robin")
greeter.greet = types.MethodType(say_hello, greeter)
greeter.greet() # Prints "Hello, Sir Robin!"
警告:在 99% 的情況下,您最好只使用常規函式或類,因為動態分配方法通常不會在 Python 中完成,并且可能會使其他開發人員感到困惑。如果你真的需要動態查找,使用像__getattr__這樣的魔術方法比使用動態方法系結要常見得多。使用此技術風險自負!
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/399450.html
