使用d时Python类不在全局中

2024-04-26 18:28:28 发布

您现在位置:Python中文网/ 问答频道 /正文

也许标题有点误导,但是我想创建一个简单的decorator,在RPC机制中将一些类方法修饰为“allowed”,但是在尝试访问类变量(python2.7.5)时,我遇到了一个奇怪的错误。检查以下代码:

class myclass():

    rpcallowedmethods = []

    def __init__(self):            
        pass

    def rpcenabled(fn):
        print fn
        print globals()
        print myclass

    @rpcenabled
    def somefunc(self,param):
        pass

c = myclass()

异常:NameError: global name 'myclass' is not defined

有人能解释一下这背后的原因吗?在

编辑: 我要问的更多的是python执行类中定义的decorator,并在类出现在globals之前就与修饰的类方法运行,所以我认为这更像是python实现中的一个逻辑“bug”,而不是一个看似明显的名称错误


Tags: 方法self标题def错误myclassdecoratorpass
3条回答

实际的类对象只有在其定义完成后才分配给其名称。因此,在定义类名时不能使用它。您可以在显式传递要填充的列表的类之外创建装饰器,也可以使用以下命令:

class myclass():
    rpcmethods = []

    def _rpcallowed(fct, l=rpcmethods):
        l.append(fct)
        return fct

    @_rpcallowed
    def myfct(): pass

请注意,默认参数(l=rpcmethods)是一种解决方法,因为在没有对类或实例的引用的情况下,无法访问函数内部的类变量。在

类的decorator之外的变体可能会被称为“更干净”,因为它是显式的和可重用的,但它的代码要多一些,具体性不强。在

奇怪的错误?在

print myclass

导致了错误。不能在其定义中使用名称myclass。。。在

你在虐待装修工。装饰者的意思是给对象添加一些东西。”以某种方式装饰它。在

更常见的方法是装饰方法和类。元类是解决这个问题的另一种方法。他们更强大,但对你目前的问题来说是杀伤力太强了。但是,直接装饰函数可能是您需要做的全部工作。以及保存在生成代理时对rpc函数的排序。在

from types import FunctionType

def enable_rpc(func):
    func.rpc_enabled = True
    return func

def rpc_enabled_class(cls):
    functions = [attr for attr in vars(cls).values() 
        if isinstance(attr, FunctionType)]
    cls._rpc_enabled_methods = [
        func for func in functions
            if getattr(func, "rpc_enabled", False)
    ]
    return cls

@rpc_enabled_class
class SampleClass(object):

    @enable_rpc
    def my_func(self):
        pass

print(SampleClass._rpc_enabled_methods)

相关问题 更多 >