如何从类变量中引用静态方法

给班上

from __future__ import annotations
from typing import ClassVar,Dict,Final
import abc

class Cipher(abc.ABC):
    @abc.abstractmethod
    def encrypt(self,plaintext: str) -> str:
        pass

    @abc.abstractmethod
    def decrypt(self,ciphertext: str) -> str:
        pass

class VigenereCipher(Cipher):
    @staticmethod
    def rotate(n: int) -> str:
        return string.ascii_uppercase[n:] + string.ascii_uppercase[:n]

    _TABLE: Final[ClassVar[Dict[str,str]]] = dict({(chr(i + ord("A")),rotate(i)) for i in range(26)})

编译失败(使用3.8.0

../cipher.py:19: in <module>
    class VigenereCipher(Cipher):
../cipher.py:24: in VigenereCipher
    _TABLE: Final[ClassVar[Dict[str,rotate(i)) for i in range(26)})
../cipher.py:24: in <setcomp>
    _TABLE: Final[ClassVar[Dict[str,rotate(i)) for i in range(26)})
E   NameError: name 'rotate' is not defined

但是,根据this帖子,rotate应该可以解决。请注意,使用类名VigenereCipher进行限定也不起作用,因为它找不到VigenereCipher(这很有意义,因为我们正在定义它)。

我可以将rotate设为模块级别的方法,并且可以使用,但是我真的不想这么做,因为它仅在VigenereCipher中需要。

也尝试了this的回答,但没有成功。

实际代码为here。单元测试为here

shuaikai006 回答:如何从类变量中引用静态方法

错误从这里引发:

_TABLE: Final[ClassVar[Dict[str,str]]] = dict({(chr(i + ord("A")),rotate(i)) for i in range(26)})

您正试图引用位于类名称空间中的变量rotate。但是python理解有其自身的范围,没有简单的方法将其与类名称空间连接。在理解评估时,没有闭包或全局变量rotate-从而调用NameError。上面的代码与您的代码相同:

def _create_TABLE():
    d = {}
    for i in range(26):
        d[chr(i + ord("A"))] = rotate(i) # -> NameError('rotate')
    return d
_TABLE: Final[ClassVar[Dict[str,str]]] = dict(_create_TABLE())
del _create_TABLE
  

如何从类变量中引用静态方法

python中的类变量是某个对象,因此它可以引用程序中的任何对象。您可以按照以下惯用语进行操作:

方法1:

class VigenereCipher(Cipher):
    @staticmethod
    def rotate(n: int) -> str:
        return string.ascii_uppercase[n:] + string.ascii_uppercase[:n]

    _TABLE: Final[ClassVar[Dict[str,str]]]

VigenereCipher._TABLE = {chr(i + ord("A")): VigenereCipher.rotate(i) for i in range(26)}

方法2:

class VigenereCipher(Cipher):
    @staticmethod
    def rotate(n: int) -> str:
        return string.ascii_uppercase[n:] + string.ascii_uppercase[:n]

    _TABLE: Final[ClassVar[Dict[str,str]]] = (
        lambda r=rotate.__func__: {chr(i + ord("A")): r(i) for i in range(26)})()

方法3:

class VigenereCipher(Cipher):
    @staticmethod
    def rotate(n: int) -> str:
        return string.ascii_uppercase[n:] + string.ascii_uppercase[:n]

    _TABLE: Final[ClassVar[Dict[str,str]]] = dict(zip(
        (chr(i + ord("A")) for i in range(26)),map(rotate.__func__,range(26)),))

方法4:

class VigenereCipher(Cipher):
    @staticmethod
    def rotate(n: int) -> str:
        return string.ascii_uppercase[n:] + string.ascii_uppercase[:n]

    _TABLE: Final[ClassVar[Dict[str,str]]] = {
        chr(i + ord("A")): r(i) for r in (rotate.__func__,) for i in range(26)}

也有基于以下方法:

您可以在相关的topic

中找到更详细的答案
本文链接:https://www.f2er.com/2864634.html

大家都在问