Python-有没有办法进行稍后声明的键入

时间:2019-06-07 00:21:20

标签: python compiler-construction interpreter typing

我正在编写解析器内容,我想在代码中进行一些“类型化”以提示类型。但是,文件的类已被引用并彼此继承。所以,我的代码现在是意大利面条:(

我尝试了无数个我可以提出的案例。我在一堂课上尝试了所有内容,然后改变了顺序。但是,什么都没有改变。尽管如此,还是出现了错误,例如“未解决的参考”

df['Predictions'] = pd.Categorical(
    df['Predictions'], categories=['Dog', 'Cat', 'Bird'], ordered=True)

(df.sort_values(['Predictions', 'Probabilities'], ascending=[True, False])
   .drop_duplicates('FolderName'))

  FolderName ImageName Predictions  Probabilities
0        ABC     MyPet         Dog           0.98
4        DEF      asdf         Dog           0.78
6        GHI     M123s         Cat           0.89

分配的声明要晚于Visitor类。因此,它会出现“无法解析的引用”错误。

2 个答案:

答案 0 :(得分:0)

针对交叉引用问题的解决方案可以是先声明您可以做什么,然后再添加其余内容。

所以您可能会遇到类似的事情:

from abc, import ABC, abstractmethod

class Expression(ABC):
    class Visitor(ABC):
        pass

class Assign(Expression):
    def accept(self, visitor: Visitor):
        # ...

@abstractmethod
def visit_assign(self, expr: Assign):
    pass

@abstractmethod
def accept(self, visitor: Visitor):
    pass

Expression.Visitor.visit_assign = visit_assign
Expression.accept = accept

答案 1 :(得分:0)

有两种方法可以做到这一点。

首先是运行from __future__ import annotations,这会将注释解析推迟到运行时,从而使您的代码可以不经修改地运行。

第二个是将您的类型注释更改为 strings ,实际上具有相同的效果:

from abc import ABC, abstractmethod

class Expression(ABC):
    class Visitor(ABC):
        @abstractmethod
        def visit_assign(self, expr: 'Assign'):
            pass

    @abstractmethod
    def accept(self, visitor: 'Visitor'):  # not needed; for consistency only
        pass

class Assign(Expression):
    def accept(self, visitor: 'Visitor'):
        pass