在py2/3迁移过程中,我们的测试工具发现了以下问题:
import types;
class Test(object):
def foo(self):
class InnerClass(object):
def innerFn():
pass
innerInst = InnerClass()
instanceRef = isinstance(innerInst.innerFn, types.MethodType)
classRef = isinstance(InnerClass.innerFn, types.MethodType)
print(type(innerInst.innerFn)) # py3: <class 'method'>
print(type(InnerClass.innerFn) # py3: <class 'function'>
# in py2: both are <type 'instancemethod'>
assert(instanceRef) # succeeds in py2 and py3
assert(classRef) # fails in py3 but succeeds in py2
在py3中,识别类和实例方法类型的推荐方法是什么?原始源代码具有导致问题的以下检查:
target = getTarget() # target can be either class method or instance method ref
if isinstance(target, types.MethodType):
do_something
REPL的链接:
InnerClass.innerFn
从来都不是类方法。它是一个未绑定的方法对象。Python3中不再存在未绑定的方法对象InnerClass.innerFn
现在解析为普通函数对象根据执行此检查的原因,您可能根本不想将,获得与旧检查类似但不等价的内容:
InnerClass.innerFn
视为一种方法。如果您这样做,您可以通过检查函数的^{如果函数的
__qualname__
是在类或另一个函数作用域内定义的,则其中至少有一个.
。如果它是在函数作用域中定义的,__qualname__
的倒数第二个组件通常是<locals>
,但它也可以是由列表理解、生成器表达式或其他类似上下文创建的函数作用域中的<listcomp>
或<genexp>
等其他一些东西。我很确定所有的函数作用域案例都是从<
开始的,而类作用域案例从来没有这样做过如果函数是在类之外定义的,然后设置为类属性,或者在其他情况下,
__qualname__
元数据与函数是否作为类属性访问不一致,并且我没有费心处理非函数输入类型,那么这就不等同于旧的检查相关问题 更多 >
编程相关推荐