Skip to main content
 首页 » 编程设计

python之在 Python 中添加的方法

2025年05月04日13over140

在 Ruby 中,可以在对象上定义方法时创建回调:

module Chatty 
  def self.method_added(method_name) 
    puts "Adding #{method_name.inspect}" 
  end 
  def self.some_class_method() end 
  def some_instance_method() end 
end 
# => Adding :some_instance_method 

Python有没有类似的回调?

请您参考如下方法:

在 Python 中,方法只是碰巧可调用的属性*。您必须连接到正在设置的属性才能看到添加到类中的新方法。

你必须使用 metaclass拦截添加到类中的新属性:

import types 
 
class NewMethodAlerter(type): 
    def __setattr__(self, name, obj): 
        if isinstance(obj, types.FunctionType): 
            print(f'New method {name} added!') 
        super().__setattr__(name, obj) 
 
 
class Demo(metaclass=NewMethodAlerter): 
    def existing_method(self): 
        pass 
 
def new_method(self): pass 
Demo.new_method = new_method 

然后看起来像这样:

>>> class Demo(metaclass=NewMethodAlerter): 
...     def existing_method(self): 
...         pass 
... 
>>> def new_method(self): pass 
>>> Demo.new_method = new_method 
New method new_method added! 

如果您想了解初始 属性集,即执行class 主体的结果,那么您有两个选择:使用元类,或在Python 中3.6 及更高版本,__init_subclass__ method .调用其中一个来创建新类,并可用于检查属性:

class InitialMethodAlerter(type): 
    def __new__(typ, name, bases, attrs): 
        for name, obj in attrs.items(): 
            if isinstance(obj, types.FunctionType): 
                print(f'Method {name} defined!') 
        return super().__new__(typ, name, bases, attrs) 
 
class Demo(metaclass=InitialMethodAlerter): 
    def existing_method(self): 
        pass 

或 __init_subclass__ 方法:

class InitialMethodAlerter: 
    @classmethod 
    def __init_subclass__(cls, **kwargs): 
        for name, obj in vars(cls).items(): 
            if isinstance(obj, types.FunctionType): 
                print(f'Method {name} defined!') 
 
class Demo(InitialMethodAlerter): 
    def existing_method(self): 
        pass 

您可能想在 What is a metaclass in Python? 阅读元类


*好吧,属性实际上是函数。功能是descriptor objects ,这会导致它们在通过实例访问时被绑定(bind)。该绑定(bind)过程会生成一个方法对象,该对象在被调用时采用原始函数并传入它绑定(bind)到的实例。