【问题标题】:In python, can I access a method in class scope (but not in function scope)在python中,我可以访问类范围内的方法(但不能访问函数范围内)
【发布时间】:2017-09-24 23:54:18
【问题描述】:

为了更好的封装,我想用同一个类中的方法来装饰实例方法。

class SomeClass(object):

    @staticmethod
    def some_decorator(func):
        def wrapped(self):
            print 'hello'
            return func(self)
        return wrapped

    @some_decorator
    def do(self):
        print 'world'

x = SomeClass()
x.do()

但是,这段代码引发了TypeError: 'staticmethod' object is not callable

现在我通过定义一个类并重载它的 new 方法来模拟一个函数来解决这个问题,但它最终是一个类,而不是一个函数。

那么我可以在类范围内访问我的函数吗?

【问题讨论】:

标签: python


【解决方案1】:

只需摆脱 @staticmethod 行。你希望some_decorator 表现得像一个普通的函数,而不是某种方法。

装饰器在类定义执行时调用,在类对象本身存在之前。类中的普通方法定义实际上只是普通的旧函数,它们在每次作为类实例的属性被调用时动态地变成方法(这将它们变成绑定方法)。但是在构建类对象本身时,您可以将它们视为普通函数。

class SomeClass(object):
    def some_decorator(func):
        def wrapped(self):
            print 'hello'
            return func(self)
        return wrapped

    @some_decorator
    def do(self):
        print 'world'

x = SomeClass()
x.do()

输出

hello
world

顺便说一句,你的装饰器有一个错误:它返回 wrapped() 而不是 wrapped


正如 chepner 在 cmets 中提到的,我们可以删除 some_decorator,以便在我们在类定义中使用完它之后它不会占用类对象中的空间。 (如果我们不小心尝试调用它,我们会得到一个错误)。我们可以在类定义之后执行del SomeClass.some_decorator,但在类定义中放置del 语句也是完全有效的:

class SomeClass(object):
    def some_decorator(func):
        def wrapped(self):
            print 'hello'
            return func(self)
        return wrapped

    @some_decorator
    def do(self):
        print 'world'

    del some_decorator

【讨论】:

  • 如果您不想弄乱您的类的命名空间,您可以将del some_decorator 添加到类定义的末尾。定义 do 后就不再需要它了。
  • @chepner 好点。我最初并没有打扰,因为在不引发 TypeError 的情况下很难在类定义之外调用它,但我想摆脱它会更干净。
猜你喜欢
  • 1970-01-01
  • 2013-06-30
  • 2014-04-05
  • 1970-01-01
  • 1970-01-01
  • 2021-06-17
  • 2016-06-23
  • 1970-01-01
  • 2014-02-07
相关资源
最近更新 更多