Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/356.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 类型暗示具有耦合继承的列表_Python_Inheritance_Pycharm_Typing - Fatal编程技术网

Python 类型暗示具有耦合继承的列表

Python 类型暗示具有耦合继承的列表,python,inheritance,pycharm,typing,Python,Inheritance,Pycharm,Typing,我将Python3.7.6与PyCharm一起使用。我希望我的代码可以作为一个很好的内部API来工作,并为对象显示代码完成,所以我希望使用类型 我正试图找到一个好的模式,用于: 有两组类,每组都有自己的继承树 一个组中的对象由另一个组中的对象列表组成 (下面的例子) 我在下面找到了一个方法,但感觉像是一个黑客。正确(或更好)的方法是什么 from typing import List, Type class Leg: def step(self): print("s

我将Python3.7.6与PyCharm一起使用。我希望我的代码可以作为一个很好的内部API来工作,并为对象显示代码完成,所以我希望使用类型

我正试图找到一个好的模式,用于:

  • 有两组类,每组都有自己的继承树
  • 一个组中的对象由另一个组中的对象列表组成
(下面的例子)

我在下面找到了一个方法,但感觉像是一个黑客。正确(或更好)的方法是什么

from typing import List, Type

class Leg:
    def step(self):
        print("step")

class DuckLeg(Leg):
    def paddle(self):
        print("splosh")

class Biped:
    def __init__(self, leg_type: Type[Leg]):
        self.legs: List[leg_type] = [leg_type(), leg_type()]

    def walk(self):
        for leg in self.legs:
            leg.step()

class Duck(Biped):
    def __init__(self):
        super().__init__(leg_type=DuckLeg)
        self.legs: List[DuckLeg] = self.legs  # A hack?

my_duck = Duck()
my_duck.walk()              # code-completion appears for .walk()
my_duck.legs[0].paddle()    # code-completion appears for .paddle()
编辑1:这个问题不是关于在哪里放置类型注释,而是如何确保代码完成在这种上下文中工作。如果以下行被注释掉

self.legs: List[DuckLeg] = self.legs

…由于duck键入,代码仍将运行,但.paile()的代码完成将不会出现,当手动输入PyCharm时,代码检查将报告:类“Leg”的未解析属性引用“paile”。

不确定这是否真的解决了您的问题,但我认为它比您建议的更简洁:

从输入导入列表中,输入
课程组:
def步骤(自我):
打印(“步骤”)
鸭腿类(腿):
def挡板(自):
打印(“splosh”)
类Biped:
腿型=腿
定义初始化(自):
#self.LegType始终为实例提供正确的支腿类型
self.legs:List[self.LegType]=[self.LegType(),self.LegType()]
def步行(自我):
对于self.legs中的leg:
第二步
类鸭子(Biped):
腿型=鸭腿
定义初始化(自):
super()。\uuuu init\uuuuu()

不确定这是否真的解决了您的问题,但我认为这比您的建议更简洁:

从输入导入列表中,输入
课程组:
def步骤(自我):
打印(“步骤”)
鸭腿类(腿):
def挡板(自):
打印(“splosh”)
类Biped:
腿型=腿
定义初始化(自):
#self.LegType始终为实例提供正确的支腿类型
self.legs:List[self.LegType]=[self.LegType(),self.LegType()]
def步行(自我):
对于self.legs中的leg:
第二步
类鸭子(Biped):
腿型=鸭腿
定义初始化(自):
super()。\uuuu init\uuuuu()

这是否回答了您的问题@感谢您的评论。这是一本有趣的读物,但不幸的是没有回答我的问题。这与在类定义中放置类型注释的位置无关(请参见上面的编辑)。但是如果您注释掉该行,并在
类鸭子(Biped)
下添加行
腿:List[DuckLeg]
,该怎么办?如果不是黑客,那会不会有同样的效果?@mkrieger1谢谢你回来。我同意这不太像黑客。遗憾的是,在没有赋值的情况下,它并没有提供我想要的好的内部API(原因我不明白)。所以仍然没有代码完成,仍然按照您建议的方式执行代码检查错误。这是否回答了您的问题@感谢您的评论。这是一本有趣的读物,但不幸的是没有回答我的问题。这与在类定义中放置类型注释的位置无关(请参见上面的编辑)。但是如果您注释掉该行,并在
类鸭子(Biped)
下添加行
腿:List[DuckLeg]
,该怎么办?如果不是黑客,那会不会有同样的效果?@mkrieger1谢谢你回来。我同意这不太像黑客。遗憾的是,在没有赋值的情况下,它并没有提供我想要的好的内部API(原因我不明白)。因此,仍然没有代码完成,仍然存在代码检查错误,按照您建议的方式执行。感谢@jdehesa的建议。我同意它更具可读性,而且运行起来也更好。不幸的是,有两个问题:在Biped中列出[self.LegType]。\uuu init\uuuu方法现在为self.LegType引发了一个红色代码检查错误“invalid self”。我尝试将其更改为Biped.LegType,但这没有帮助,因为Biped.LegType是Leg,即使在init中也是如此。我猜是一个不变的类变量。回到原来的问题,没有显示.pable()的代码检查,手动输入时,代码检查会将其标记为警告。谢谢你。我学到了一些东西:)谢谢你的建议@jdehesa。我同意它更具可读性,而且运行起来也更好。不幸的是,有两个问题:在Biped中列出[self.LegType]。\uuu init\uuuu方法现在为self.LegType引发了一个红色代码检查错误“invalid self”。我尝试将其更改为Biped.LegType,但这没有帮助,因为Biped.LegType是Leg,即使在init中也是如此。我猜是一个不变的类变量。回到原来的问题,没有显示.pable()的代码检查,手动输入时,代码检查会将其标记为警告。谢谢你。我学到了一些东西:)