当前位置: 首页 > 知识库问答 >
问题:

类型为(self)[重复]的方法签名参数

邹华皓
2023-03-14

当我定义一个类时,我如何在它的方法签名中包含必须属于同一类的参数?我正在构建一个应该这样工作的图结构,但是这里有一个简化的例子:

class Dummy:
    def __init__(self, value: int, previous: Dummy=None):
        self._value = value
        self._previous = previous

    @property
    def value(self):
        return self._value

    def plus_previous(self):
        return self.value + self._previous.value

d1 = Dummy(7)
d2 = Dummy(3, d1)
d2.plus_previous()

这将导致以下错误:

NameError: name 'Dummy' is not defined

我的意思是,我可以用Python 2的方式来做,但是我希望有比这更Python-3-ic的解决方案:

class Dummy:
    def __init__(self, value: int, previous=None):
        assert type(previous) is Dummy or previous is None
        ...

共有1个答案

魏安然
2023-03-14

虽然我同意,但这是一个相当丑陋的黑客行为,您也可以使用字符串作为类型提示:

class Dummy:
    def __init__(self, value: int, previous: 'Dummy'=None):
        self._value = value
        self._previous = previous

    @property
    def value(self):
        return self._value

    def plus_previous(self):
        return self.value + self._previous.value

如PEP-484关于类型提示所述:

当类型提示包含尚未定义的名称时,该定义可以表示为字符串文本,稍后进行解析。

这种情况通常发生在容器类的定义中,其中被定义的类出现在某些方法的签名中。例如,以下代码(简单二叉树实现的开始)不起作用:

class Tree:
    def __init__(self, left: Tree, right: Tree):
        self.left = left
        self.right = right

为了解决这个问题,我们写道:

class Tree:
    def __init__(self, left: 'Tree', right: 'Tree'):
        self.left = left
        self.right = right

字符串文字应该包含一个有效的Python表达式(即,compile(lit, '', 'ava')应该是一个有效的代码对象),并且一旦模块被完全加载,它应该无错误地进行计算。计算它的本地和全局命名空间应该与计算相同函数的默认参数的命名空间相同。

然而,这种攻击的一个问题是,如果在IDE中进行重命名,IDE肯定会不考虑这些字符串文本,因此无法重命名这些字符串。

 类似资料:
  • 我想这样设置参数的类型: 当我尝试这样做时,会引发错误:NameError:名称'Tree'未定义

  • 我有一个方法,我想在其中接受必须扩展抽象类的类类型。之间的区别是什么 ? 在第二种情况下,我不能直接引用方法内部的类型。哪些类类型可以传递给这两个方法有什么不同吗?

  • 我已经尝试了网络上提供的所有解决方案,但都无效。请尽快提供帮助。同步错误: 生成文件“C:\Users\AH\U GL\Desktop\apps android commons\apps\Build”。格拉德尔线:149 评估项目“:app”时出现问题。 没有方法的签名:build_bacf6ncg9oj63qiyhi1id1rfi.android()适用于参数类型:(build_bacf6ncg

  • 在java中,我们可以缩小返回类型和throws异常类型(甚至删除throws子句): 但是,参数类型呢(如果A采用< code>T,那么为什么B不采用< code >?超级T)如: 让我们考虑一下我认为完全符合逻辑的这段代码: 所以我要说的是,在使用的代码上下文中仍然有效。

  • 问题:评估项目':app'时出现问题。 方法:build_dxc6m5s863o0nfrfjdg2bqjp.android()的签名不适用于参数类型:(build_dxc6m5s863o0nfrfjdg2bqjp$_run_closure1)值:[build_dxc6m5s863o0nfrfjdg2bqjp$_run_closure1@18112963] 分级文件:

  • 为什么编译器匹配字符串重载,而不是对象重载?