给定班级
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, str]]] = dict({(chr(i + ord("A")), rotate(i)) for i in range(26)})
../cipher.py:24: in <setcomp>
_TABLE: Final[ClassVar[Dict[str, str]]] = dict({(chr(i + ord("A")), rotate(i)) for i in range(26)})
E NameError: name 'rotate' is not defined
但是,根据这篇文章,rotate
应该可以解决。请注意,使用类名进行限定VigenereCipher
也不起作用,因为找不到它VigenereCipher
(这很有意义,因为我们正在定义它)。
我可以创建rotate
一个模块级方法,并且该方法行得通,但是我真的不想这么做,因为它只在中需要VigenereCipher
。
也尝试了这个答案,但没有成功。
错误是从这里引发的:
_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)}
方法二:
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)}
也有基于以下方法:
locals
功能;__init__subclass__
方法;__set_name__
;global
关键字。您可以在相关主题中找到更详细的答案
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句