我有这段代码:
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]()
如何解决?
答案 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
调用 process
和 self
。您可以在任何地方使用 A.open()
和 A.process()
调用它们,也可以在类内仅使用 open()
和 process()
而无需 A.
。