'staticmethod'对象不是可调用的开关/ case

时间:2017-01-29 13:10:30

标签: python python-2.7

我有这段代码:

  select * from territory where region_id   in  (select region_id from region where devision_id=<division id>)

当我运行此操作时,我不断收到错误:

class A(object):
    @staticmethod
    def open():
        return 123
    @staticmethod
    def proccess():
        return 456


    switch = {
        1: open,
        2: proccess,   
        }
obj = A.switch[1]()

如何解决?

2 个答案:

答案 0 :(得分:35)

您将未绑定的 staticmethod对象存储在字典中。此类对象(以及classmethod对象,函数和property对象)仅通过descriptor protocol绑定,方法是将该名称作为类或实例上的属性进行访问。直接访问类主体中的staticmethod对象不是属性访问。

在创建类之后创建字典(因此您可以将它们作为属性访问),或者显式绑定,或者在将原始函数存储到字典中之前提取原始函数。

请注意,staticmethod对象的“绑定”仅仅意味着仅忽略上下文;绑定staticmethod返回基础函数不变。

因此,您的选择是取消字典并使用属性触发描述符协议:

class A(object):
    @staticmethod
    def open():
        return 123
    @staticmethod
    def proccess():
        return 456

A.switch = {
    1: A.open,
    2: A.proccess,   
}

或显式绑定,传入虚拟上下文(无论如何都会被忽略):

class A(object):
    @staticmethod
    def open():
        return 123
    @staticmethod
    def proccess():
        return 456

    switch = {
        1: open.__get__(object),
        2: proccess.__get__(object),   
    }

或使用__func__属性直接访问基础函数:

class A(object):
    @staticmethod
    def open():
        return 123
    @staticmethod
    def proccess():
        return 456

    switch = {
        1: open.__func__,
        2: proccess.__func__,   
    }

但是,如果您要做的只是为一堆函数提供命名空间,那么您不应该首先使用类对象。将功能放在模块中。这样你就不必首先使用staticmethod装饰器,也不必再打开它们。

答案 1 :(得分:7)

除了 Pieters 的回答,您还可以删除 @staticmethod

class A(object):
    def open():
        return 123

    def proccess():
        return 456

    switch = {
        1: open,
        2: proccess,   
        }

obj = A.switch[1]()

但是,通过这种方式,您无法使用 open 调用 processself。您可以在任何地方使用 A.open()A.process() 调用它们,也可以在类内仅使用 open()process() 而无需 A.