【问题标题】:How to create nested type of data in Python?如何在 Python 中创建嵌套类型的数据?
【发布时间】:2022-12-23 14:23:39
【问题描述】:

我想确定,当类创建是某种类型时传递的参数之一。这是一个例子:

from __future__ import annotations
from dataclasses import dataclass


@dataclass(frozen=True, order=True)
class ListItems:
    items: list | str | int | ListItems


class PList:
    def __init__(self, name: str, items: ListItems):
        self.type = "list"
        self.name = name
        self.items = items


a = PList('asd', ['asd'])

接下来的想法是:items只能是stringint数据类型的列表或其他清单stringint,它是嵌套的。例如:

[] OK
[1,2,'asd'] OK
[[1,2,3],'asd',[]] OK
[{}] NOT OK
['test', [{}]] NOT OK

有没有可能在 Python 中实现这样的东西?

我对 Python OOP 不是很熟悉,但据我所知,没有像其他编程语言那样的接口和/或抽象类的本地实现。

附言: 你看到的代码,只是我的实现尝试,它没有用。

【问题讨论】:

  • 您希望参数的类型在运行时或由静态检查器(例如 mypy)或两者进行检查吗?
  • 您可以检查类型并基于该类型允许或不允许?
  • @mkrieger1 实际上,仅在运行时
  • 然后@dokichan你为什么要问类型提示

标签: python oop


【解决方案1】:

def __init__(self, name: str, items: ListItems):

items: ListItems 位表示 items 应该是一个 ListItems 对象,它没有通过 ListItems 正在做的事情的逻辑,它只是比较它是什么类型。

我没有太多打字经验,但我认为您正在寻找items: list[str|int] 请注意,对于列表,有正常的列表类型提示,然后在打字库中也有一个。不确定是否有区别,我只知道普通列表类型提示是小写的(list 而不是 List,就像在打字库中一样),而且它相对较新(我认为是 3.11)

【讨论】:

  • 这里的问题是,如果您有items: list[str | int],您可以将对象放入此列表中。像这样:a = PList('asd', ['asd', {}]),它会起作用
  • 是的,我不确定那么朋友。我只想说那是你要找的地方。也许创建一个类并从打字库继承大写字母 L List,你可以改变一些行为
  • 澄清一下,您是在寻找像 IDE 中的黄色下划线这样的输入错误,还是在类型错误时引发异常?因为类型提示不会引发异常
  • @dokichan 的课程,这些是类型提示。它们不会在运行时强制执行。另外 {} 是一个 dict,而不是一个“对象”(好吧,它一个对象,但是一切是一个对象)
  • @Nate 不,从typing.List 继承不会改变任何东西,无论如何,不​​推荐使用typing.List
【解决方案2】:

简短回答你的问题Python是一个动态类型语。在代码运行之前,它不知道变量的类型。所以声明是没有用的。它所做的是,它将该值存储在某个内存位置,然后将该变量名绑定到该内存容器。并使容器的内容可以通过该变量名访问。所以数据类型无关紧要。因为它将在运行时了解值的类型。

名称在执行时绑定到对象通过赋值语句,可以在程序执行过程中为不同类型的对象绑定名称。函数和对象可以在运行时更改。

在动态类型语言中,变量只是一个绑定到的值 一个名字;该值有一个类型——比如“整数”或“字符串”或“列表” -- 但变量本身没有。你可以有一个变量,现在,它保存一个数字,如果你需要,稍后可以为它分配一个字符串 它改变。在静态类型语言中,变量本身具有 一种;如果你有一个整数变量,你将无法 稍后为其分配任何其他类型的值。

从以下几点你会发现在python代码中显式预定义数据类型不会强制它只接受这种类型:

(因为类型错误只是程序中所有可能出错的事情的一小部分);结果,动态语言的程序员依赖于他们的测试 套件来捕获这些和所有其他错误,而不是使用 专用的类型检查编译器。

查看此 reference 了解更多信息。

【讨论】:

  • 我不同意“没有意义”。使用类型提示有很多很好的理由,此外,您可以使用静态类型检查器来验证代码的类型正确性。
  • @juanpa.arrivillaga 我的意思是使用类型提示预定义数据类型不会强制 python 解释器只接受变量的这种数据类型,因为它会在运行时知道类型。
  • 当然可以,但这与说“没有意义”不是一回事。
【解决方案3】:

我不确定您是否需要类 listItems。只需在 init 方法中使用一个简单的 if 语句。

class PList:
  def __init__(self, name, items):
    self.type = 'list'
    self.name = name
    if type(items) is list or type(items) is str or type(items) is int:
      self.items = items

【讨论】:

  • 我没有投反对票,但类型提示是一回事,它的工作方式与打字稿非常相似
猜你喜欢
  • 2019-01-04
  • 1970-01-01
  • 1970-01-01
  • 2021-12-03
  • 2013-12-30
  • 2019-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多