【问题标题】:Python Changing name of method [duplicate]Python更改方法的名称[重复]
【发布时间】:2018-02-06 20:24:01
【问题描述】:

使用 python 3.6。我正在尝试编写一些代码,允许我在类方法上放置一个唯一标识符。

这是一个例子:

def test(func):
    def wrap():
        pass
    wrap.__name__ += '_TEST'
    return wrap

class example:
    @test
    def method(self):pass

控制台:

import inspect
Bar = example()
inspect.getmembers(Bar, predicate=inspect.ismethod)
Out[3]: 
[('method', # Name didn't change 
<bound method test.<locals>.wrap of <__main__.example object at 
0x000002670E073EF0>>)]
Bar.method.__name__
Out[4]: 'wrap_TEST'

我希望能够遍历一个类的方法,并且只执行我用我的装饰器标记的方法。这个可以吗?

【问题讨论】:

  • 方法查找不会返回实际函数,它们本身就是函数的薄包装。如果您检查,您的实际功能已被重命名:Bar.method.__func__.__name_.
  • 你能解释一下装饰者想要达到什么目的吗?这样做似乎有点太复杂了。装饰器是真的改变了函数的行为方式还是只改变了名字?
  • 这也是由于gemembers() works 的方式,它使用dir() 来获取成员,并且总是会返回method,因为这就是实例或类字典中存在的内容。
  • 是的,我会记住的:)
  • @ChristianDean 在投票结束之前阅读了该问题,这与您找到的问题不重复..

标签: python decorator inspect


【解决方案1】:

与其尝试更改已创建方法的名称,不如使用函数和方法是第一类对象这一事实为方法本身分配属性。

在以下代码中,您可以创建一个简单的装饰器,将属性TEST 添加到您要测试的方法中。

def test(func):
    func.TEST = True
    return func


class example:
    @test
    def method(self):
        pass

ex = example()
ex.method.TEST
# returns:
True

【讨论】:

  • 干杯,就是这样!
【解决方案2】:

您可以使用布尔标志来标记函数。这是我的建议:

import inspect

def mark(func):
    func.flag = True
    return func

class C:
    @mark
    def a(self):
        pass

    @mark
    def b(self):
        pass

    def c(self):
        pass

methods = [m for n, m in inspect.getmembers(C) if hasattr(m, 'flag')]
print([m.__name__ for m in methods]) #=> ['a', 'b']

【讨论】:

    猜你喜欢
    • 2012-12-18
    • 2011-01-16
    • 2020-02-26
    • 1970-01-01
    • 2017-04-17
    • 1970-01-01
    • 1970-01-01
    • 2015-11-04
    • 2016-03-17
    相关资源
    最近更新 更多