每当调用类的方法时打印方法名称

每当调用类的方法时打印方法名称

本文介绍了Python - 每当调用类的方法时打印方法名称的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在每次调用特定类的方法时执行某些操作(例如记录方法名称)。

I need to perform certain operations everytime the methods of a particular class is called (for example log the method name). How can this be achieved in Python in a generic way?

推荐答案

在元类中装饰可调用的属性:

Decorate callable attributes from within a metaclass:

from functools import wraps

def _log_method(val):
    @wraps(val)
    def wrapper(*a, **ka):
        print(val.__name__, 'is called')
        val(*a, **ka)
    return wrapper

class LogMethodCalls(type):
    def __new__(cls, cls_name, bases, attrs):
        for name, attr in attrs.items():
            if callable(attr):
                attrs[name] = _log_method(attr)
        return type.__new__(cls, cls_name, bases, attrs)

class Foo(metaclass=LogMethodCalls):
    def my_method(self):
        pass

Foo().my_method() # my_method is called

警告 :此代码仅适用于实例方法,使用或(因为 classmethod staticmethod 对象不是可调用的 - 它们只是非数据描述符)。

Warning: This code only works for instance methods, methods that were decorated with @classmethod or @staticmethod will not be logged (because classmethod and staticmethod objects are not callable - they're just non-data descriptors).

以下同样适用于类方法和静态方法:

The following works for class methods and static methods as well:

from functools import wraps

def _log_method(val):
    @wraps(val)
    def wrapper(*a, **ka):
        print('calling', val.__name__)
        val(*a, **ka)
    return wrapper

class LogMethodCalls(type):
    def __new__(cls, cls_name, bases, attrs):
        for name, attr in attrs.items():
            if callable(attr):
                attrs[name] = _log_method(attr)
            elif isinstance(attr, (classmethod, staticmethod)):
                attrs[name] = type(attr)(_log_method(attr.__func__))
        return type.__new__(cls, cls_name, bases, attrs)

class Foo(metaclass=LogMethodCalls):

    def my_instance_method(self):
        pass

    @classmethod
    def my_class_method(cls):
        pass

    @staticmethod
    def my_static_method():
        pass

Foo().my_instance_method() # calling my_instance_method
Foo.my_class_method() # calling my_class_method
Foo.my_static_method() # calling my_static_method

他们有 __ func __ 属性,我们可以装饰。

They have __func__ attributes that we can decorate.

请注意,您需要使用

class Foo(object):
    __metaclass__ = LogMethodCalls

在Python 2中。

in Python 2.

这篇关于Python - 每当调用类的方法时打印方法名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 09:41