将python 2.7中的im_类转换为python 3.8

将python 2.7中的im_类转换为python 3.8,python,Python,我正在将一些python 2.7代码转换为python 3.8。有一件事我一直在想,那就是如何获得一份关于im_班工作的参考资料。原始代码如下所示: class UpdateDbQueue(): def __init__(self, **kwargs): self.job = kwargs["job"] self.method = self.job self.cls = self.job.im_class self.name

我正在将一些python 2.7代码转换为python 3.8。有一件事我一直在想,那就是如何获得一份关于im_班工作的参考资料。原始代码如下所示:

class UpdateDbQueue():
    def __init__(self, **kwargs):
        self.job = kwargs["job"]
        self.method = self.job
        self.cls = self.job.im_class
        self.name = "{}.{}".format(self.cls.__name__, self.method.__name__)
运行调试器显示kwargs[“作业”]等于
。python2to3实用程序将代码转换为:

class UpdateDbQueue():
    def __init__(self, **kwargs):
        self.job = kwargs["job"]
        self.method = self.job
        self.cls = self.job.__self__.__class__
        self.name = "{}.{}".format(self.cls.__name__, self.method.__name__)
返回一个错误:

self.cls = self.job.__self__.__class__
AttributeError: 'function' object has no attribute '__self__'
你知道怎么解决这个问题吗?我尝试将其简单地更改为self.job。,但出现了一个错误
KeyError:'DateRange.get\u events'

编辑-这是DateRange类的一个片段

类日期范围(db.Model): id=db.Column(db.DateTime,主键=True)

def get_事件(self,行=10000):
#从数据库获取事件
定义报告(自我):
返回“”格式(self.id)

看起来像
im\u类
属性是在python2中找到的:

>>> sys.version
'2.7.16 (default, Nov  9 2019, 05:55:08) \n[GCC 4.2.1 Compatible Apple LLVM 11.0.0 (clang-1100.0.32.4) (-macos10.15-objc-s'
>>> class S:
...    def f(s):
...      pass
...
>>> 'im_class' in dir(S.f)
True
由于在python3中没有无界方法,因此这种类型的对象中不再存在无界方法:

In [9]: sys.version
Out[9]: '3.7.3 (default, Nov 15 2019, 04:04:52) \n[Clang 11.0.0 (clang-1100.0.33.16)]'

In [10]: class S:
    ...:     def f(s):
    ...:         pass
    ...:

In [11]: 'im_class' in dir(S.f)
Out[11]: False
python2to3转换工具似乎假设在python3中有一个有界方法:

In [12]: sys.version
Out[12]: '3.7.3 (default, Nov 15 2019, 04:04:52) \n[Clang 11.0.0 (clang-1100.0.33.16)]'

In [13]: class S:
    ...:     def f(s):
    ...:         pass
    ...:

In [14]: '__self__' in dir(S().f) ## bounded by S()
Out[14]: True
但是,根据您关于
kwargs['job']

运行调试器显示kwargs[“作业”]等于

这只是一个普通函数,这就是python3中的无界方法

要尝试的一件事是,在分配给一个实例后,使用以下方法将函数绑定到本地方法:

import types
class UpdateDbQueue():
    def __init__(self, **kwargs):
        self.job = types.MethodType(kwargs['job'], self)
这样您就拥有了必要的属性:

In [26]: def f(s):
    ...:     pass
    ...:

In [27]: class S:
    ...:     def __init__(self):
    ...:         self.f = types.MethodType(f, self)
    ...:         if '__self__' in dir(self.f):
    ...:             print("I have __self__")
    ...:
    ...:

In [28]: S()
I have __self__
Out[28]: <__main__.S at 0x111711dd8>
[26]中的
:定义f(s):
…:通过
...:
在[27]中:S类:
…:def_uuuinit_uuu(self):
…:self.f=types.MethodType(f,self)
…:如果dir(self.f)中的“\uuuuu self\uuuuuu”:
…:打印(“我有自己的”)
...:
...:
在[28]:S()中
我有__
出[28]:
但是,
job
需要作为有界方法调用(因此实例作为第一个参数传递,以此类推)

编辑:
根据您的问题编辑,如果您使用适当的有界方法调用这个类,它应该可以工作,那么您如何调用
UpdateDbQueue
类呢

你试过原版的吗
self.cls=self.job.im\u class
?什么是日期范围?什么是
DateRange.getevents
?是否有
im\u class
属性?@wwii
im\u class
是python2中有界方法的数据模型的一部分是的,我尝试了原始方法,但得到:
AttributeError:'function'对象没有属性'im\u class'
。我将使用DateRange更新代码。如何调用
UpdateDbQueue
并传递
job
属性?根据上次更新,它应该类似于
UpdateDbQueue(job=DateRange().get_events)
它是通过
update_registry.register(UpdateDbQueue(job=DateRange.get_events,action_table=“date_range”)
调用的:update_registry.register(UpdateDbQueue(job=DateRange.get\u events,action\u table=“date\u range”)…我认为
self.cls=self.job.\uuu class\uuuu
应该是正确的。@wwii不是因为普通函数的(py3中的无界方法)
\uuuu class\uuuu
函数
而不是
日期范围
。@Casey您能改为像这样调用类
DateRane()。获取\u事件
In [26]: def f(s):
    ...:     pass
    ...:

In [27]: class S:
    ...:     def __init__(self):
    ...:         self.f = types.MethodType(f, self)
    ...:         if '__self__' in dir(self.f):
    ...:             print("I have __self__")
    ...:
    ...:

In [28]: S()
I have __self__
Out[28]: <__main__.S at 0x111711dd8>