将函数修饰符向后移植到 python2.1

发布于 2024-07-28 13:30:36 字数 820 浏览 10 评论 0原文

我有一些用 python 2.4++ 开发的代码,你敢打赌,我必须将其向后移植到 python 2.1!

函数装饰器非常有吸引力,以至于我在一些地方使用了 @classmethod,但没有注意到它仅从 2.4 版本开始可用。 函数修饰符提供了相同的功能,但它们出现在 python 2.2 中。 CFR: http://www.python.org/dev/peps/pep-0318 /

现在我们的一些客户似乎仍然依赖于 python 2.1(ArcGIS 9.1 附带它并且使其不可升级),甚至连功能修饰符都不可用...

我一直在寻找一些功能修饰符python 2.1 中的定义,但我没有找到任何(我的意思是:工作)。 有人成功解决这个问题吗?

更具体地说,我需要一种在 python 2.1 中运行此 2.4 代码的方法:

Python 2.4.6 (#2, Mar 19 2009, 10:00:53) 
[GCC 4.3.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> class sic:
...   def f(cls):
...     print cls.__name__
...   f = classmethod(f)
... 
>>> sic().f()
sic
>>> sic.f()
sic
>>> 

I have some code I developed in python 2.4++ and you bet, I have to backport it to python 2.1!

function decorators were so attractive that I have used @classmethod at a few spots, without taking notice of the fact that it is only available starting at version 2.4. the same functionality is offered by function modifiers but these appeared in python 2.2. cfr: http://www.python.org/dev/peps/pep-0318/

now some of our customers appear to be still dependent on python 2.1 (ArcGIS 9.1 ships with it and makes it not upgradable), where not even the function modifiers are available...

I have been looking for some function modifier definitions in python 2.1, but I did not find any (I mean: working). anybody successfully solved this problem?

to be more concrete, I need a way to run this 2.4 code in python 2.1:

Python 2.4.6 (#2, Mar 19 2009, 10:00:53) 
[GCC 4.3.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> class sic:
...   def f(cls):
...     print cls.__name__
...   f = classmethod(f)
... 
>>> sic().f()
sic
>>> sic.f()
sic
>>> 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

痴情换悲伤 2024-08-04 13:31:02

如果只是 @classmethod 需要向后移植到 Python 2.1。
有一个python2.1中Classmethod模拟的配方
希望这有帮助。

If just the @classmethod need to be backported to Python 2.1.
There is a recipe of Classmethod emulation in python2.1
Hope this help.

半枫 2024-08-04 13:30:55

就像我在 2.1 静态方法的旧配方中一样:

class staticmethod:
    def __init__(self, thefunc): self.f = thefunc
    def __call__(self, *a, **k): return self.f(*a, **k)

您应该能够执行 2.1 类方法:

class classmethod:
    def __init__(self, thefunc): self.f = thefunc
    def __call__(self, obj, *a, **k): return self.f(obj.__class__, *a, **k)

当然没有 @-syntax,而是旧方法(如 2.2 中):

class sic:
  def f(cls): ...
  f = classmethod(f)

如果这不'不起作用(抱歉,自从我有一个 Python 2.1 可供测试以来已经很多年了),需要更明确地提供该类 - 并且由于您在类对象存在之前调用 classmethod,因此需要按名称命名 - - 假设一个全局类,

class classmethod2:
    def __init__(self, thefunc, clsnam):
        self.f = thefunc
        self.clsnam = clsnam
    def __call__(self, *a, **k):
        klass = globals()[self.clsnam]
        return self.f(klass, *a, **k)

class sic2:
  def f(cls): ...
  f = classmethod2(f, 'sic2')

很难找到优雅的方法来获取类对象(抑制对 self 的需求是容易的部分,而静态方法就足够了:您只需将函数包装成非函数可调用),因为2.1 只有遗留(旧式类),没有可用的元类,因此没有真正好的方法让 sic2.f() 神奇地获得 cls。

由于 2.1 中缺少 @ 语法不可避免地需要编辑使用 @classmethod 的代码,因此另一种方法是将功能(将某些方法装饰为“类”方法)移至class语句(好处是当时类对象确实存在)。

class classmethod3:
    def __init__(self, thefunc, klass):
        self.f = thefunc
        self.klass = klass
    def __call__(self, *a, **k):
        return self.f(self.klass, *a, **k)

def decorate(klass, klassmethodnames):
  for n in klassmethodnames:
    thefunc = klass.__dict__[n]
    setattr(klass, n, classmethod3(thefunc, klass))

class sic2:
  def f(cls): ...
  def g(self): ...
  def h(cls): ...
decorate(sic2, ['f', 'h'])

Just like in my old recipe for 2.1 staticmethod:

class staticmethod:
    def __init__(self, thefunc): self.f = thefunc
    def __call__(self, *a, **k): return self.f(*a, **k)

you should be able to do a 2.1 classmethod as:

class classmethod:
    def __init__(self, thefunc): self.f = thefunc
    def __call__(self, obj, *a, **k): return self.f(obj.__class__, *a, **k)

No @-syntax of course, but rather the old way (like in 2.2):

class sic:
  def f(cls): ...
  f = classmethod(f)

If this doesn't work (sorry, been many many years since I had a Python 2.1 around to test), the class will need to be supplied more explicitly -- and since you call classmethod before the class object exists, it will need to be by name -- assuming a global class,

class classmethod2:
    def __init__(self, thefunc, clsnam):
        self.f = thefunc
        self.clsnam = clsnam
    def __call__(self, *a, **k):
        klass = globals()[self.clsnam]
        return self.f(klass, *a, **k)

class sic2:
  def f(cls): ...
  f = classmethod2(f, 'sic2')

It's really hard to find elegant ways to get the class object (suppressing the need for self is the easy part, and what suffices for staticmethod: you just need to wrap the function into a non-function callable) since 2.1 had only legacy (old-style classes), no usable metaclasses, and thus no really good way to have sic2.f() magically get that cls.

Since the lack of @ syntax in 2.1 inevitably requires editing of code that uses @classmethod, an alternative is to move the functionality (decorating some methods to be "class" ones) to right AFTER the end of the class statement (the advantage is that the class object does exist at that time).

class classmethod3:
    def __init__(self, thefunc, klass):
        self.f = thefunc
        self.klass = klass
    def __call__(self, *a, **k):
        return self.f(self.klass, *a, **k)

def decorate(klass, klassmethodnames):
  for n in klassmethodnames:
    thefunc = klass.__dict__[n]
    setattr(klass, n, classmethod3(thefunc, klass))

class sic2:
  def f(cls): ...
  def g(self): ...
  def h(cls): ...
decorate(sic2, ['f', 'h'])
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文