Python 在创建类(而不是实例)时,是否有方法获取要调用的(静态)方法?
再一次,有点惊讶没有找到这个问题的答案 我提问的现实原因是: 我有一本关于类中常量的字典Python 在创建类(而不是实例)时,是否有方法获取要调用的(静态)方法?,python,class,methods,static,Python,Class,Methods,Static,再一次,有点惊讶没有找到这个问题的答案 我提问的现实原因是: 我有一本关于类中常量的字典 class MySQLConstants(): DECIMAL = 0 TINY = 1 SHORT = 2 LONG = 3 FLOAT = 4 DOUBLE = 5 ... etc. 我想要一本字典,这样我就可以在给定数字的情况下找到常数。。。很简单: fieldTypeDic = {} for fieldType in dir( MySQLConstants ):
class MySQLConstants():
DECIMAL = 0
TINY = 1
SHORT = 2
LONG = 3
FLOAT = 4
DOUBLE = 5
... etc.
我想要一本字典,这样我就可以在给定数字的情况下找到常数。。。很简单:
fieldTypeDic = {}
for fieldType in dir( MySQLConstants ):
value = getattr( MySQLConstants, fieldType )
fieldTypeDic[ value ] = fieldType
。。。在执行class definition语句后,将其设置为MySQLConstants的@static方法,并通过调用MySQLConstants.createDic()调用它将非常简单。。。但我只是想知道是否有任何方法可以在创建类(注意,我不是说创建这个类的实例!)时运行一个不可避免的@static方法…您可以创建一个元类,在创建类时添加行为,但您的用例非常简单,可以在需要时直接提取字典:
>>> class MySQLConstants:
DECIMAL = 0
TINY = 1
SHORT = 2
LONG = 3
FLOAT = 4
DOUBLE = 5
>>> vars(MySQLConstants)
{'__module__': '__main__', 'SHORT': 2, 'DOUBLE': 5, 'DECIMAL': 0, 'FLOAT': 4, 'LONG': 3, 'TINY': 1, '__doc__': None}
下面是一个使用元类的解决方案:
class ConstantDictMeta(type):
def __new__(cls, name, bases, dct):
fieldTypeDic = dict((v, k) for k, v in dct.items() if k.isupper())
dct["fieldTypeDic"] = fieldTypeDic
return type.__new__(cls, name, bases, dct)
class MySQLConstants():
__metaclass__ = ConstantDictMeta
DECIMAL = 0
TINY = 1
SHORT = 2
LONG = 3
FLOAT = 4
DOUBLE = 5
>>> MySQLConstants.fieldTypeDic
{0: 'DECIMAL', 1: 'TINY', 2: 'SHORT', 3: 'LONG', 4: 'FLOAT', 5: 'DOUBLE'}
要直接回答问题,请选择“是”:
class MySQLConstants():
DECIMAL = 0
TINY = 1
SHORT = 2
LONG = 3
FLOAT = 4
DOUBLE = 5
def create_dict(cls):
fieldTypeDic = {}
if not isinstance(cls, dict):
cls = cls.__dict__
for key, value in cls.items():
if isinstance(value, int):
fieldTypeDic[ value ] = key
cls['fieldTypeDic'] = fieldTypeDic
create_dict(vars())
create_dict = classmethod(create_dict)
注意create_dict的重写,特别是在类创建期间调用它之后将其指定为classmethod
如果这是一次性使用方法,我倾向于这样做:
class MySQLConstants():
lookup = {}
local = vars()
for i, name in enumerate('DECIMAL TINY SHORT LONG FLOAT DOUBLE'.split()):
local[name] = i
lookup[i] = name
del local, i, name
这将在一个整洁的包中创建所有名称,并创建一个反向查找字典。事实上,它比使用元类简单得多,而且不需要“classmethod”:
class MySQLConstants():
DECIMAL = 0
TINY = 1
SHORT = 2
LONG = 3
FLOAT = 4
DOUBLE = 5
def create_dict( dicForReversing ):
fieldTypeDic = {}
for key, value in dicForReversing.items():
if isinstance(value, int):
fieldTypeDic[ value ] = key
return fieldTypeDic
fieldTypeDic = create_dict( vars() )
但特别要感谢Ethan Furman,他展示了在创建类的过程中可以实现一些事情
注意:如果您预期您的键有多个值(MySQLdb常量就是这种情况),那么最好的处理方法可能如下
ENUM = 247
CHAR = TINY
INTERVAL = ENUM
def create_dict( dicForReversing ):
fieldTypeDic = {}
for key, value in dicForReversing.items():
if isinstance(value, int):
if not value in fieldTypeDic:
fieldTypeDic[ value ] = set()
fieldTypeDic[ value ].add( key )
return fieldTypeDic
fieldTypeDic = create_dict( vars() )
您也可以直接使用getattr(MySQLConstants,'TINY')进行查找,而不是创建dict。。。除了我想从提供的数字中获取常量的名称之外……首先将常量声明为字典,自动生成反向字典,然后使用
\uuuu getattr\uuuuu
使它们看起来像类成员。@Russellborogve抱歉,我不清楚。。。当你说“自动生成”。。。这可能必须发生在方法内部。。。那么,我们不是回到了创建类时调用的方法的原始问题了吗?@MikCorvent-我的建议与Ethan Furman的第二个示例类似。除了。。。然后,每当我想进行查找时,我都必须反转映射。。。每个人都需要时间time@mike啮齿类动物:是的,这需要几十纳秒。@JochenRitzel,但我没有几十纳秒的空闲时间。。。我有点疯狂,我喜欢用宝贵的纳秒来对堆栈溢出的postsum做出稍微偏离波束和文字的回答。。。我尝试了您的第一段代码,结果发现AttributeError:“stringmap”对象没有属性“dict”。然而,这似乎表明,通过将“cls”作为参数传递,确实有一种我正在寻找的方法。谢谢你给我看这个。将继续进行实验…至于你的第二个例子,我假设常数的编号不是完全任意的。。。例如,我们可能希望在一个特定的数字范围内分组不同的整数类型(尽管实际上,这些数字的MySQLdb赋值似乎没有提供太多合理的分组…(尽管有点…)稍后:对不起,啤酒太多了…当然是参数名称“cls”的选择跟这件事毫无关系……但你做了一件非常聪明的事……明天早上我会设法弄明白是什么!