Python - 如何传递给 class 对象的函数参数类型(键入)

Python - how to pass to a function argument type of a class object (typing)

我想 python 3.7(不确定)可以将变量名和变量类型传递给函数。我想知道的是是否有可能传递特定 class.

的类型

你可以通过同样的方式:

def foo_func(i: int) -> None:
    pass

如果我有 class 让我们说:

class foo_class(object):
    pass

如何转换 foo_func 以接收 foo_class 而不是 int 类型?

此外,如果 foo_class 是另一个 class 的继承,我可以从父级强加一个更通用的类型吗?例如,如果我愿意,

class A(foo_class):
     pass

class B(foo_class):
     pass

如何根据其父级传递 AB

我的意思是:

def foo_func(obj: foo_class_type) -> None:
    pass

foo_func(A())
foo_func(B())

根据您是要传递 class(类型)还是 class 的实例,您正在寻找 typing.Type 或只是 class.

这里有一个简单的例子来解释这两种情况:

from typing import Type, TypeVar


class Vehicle:
    def __init__(self):
        print("Creating a %s" % self.__class__.__name__)

    def move(self):
        print("This %s is moving…" % self.__class__.__name__)

TVehicle = TypeVar("TVehicle", bound=Vehicle)

class Car(Vehicle):
    def honk(self) -> None:
        print("tuuuuut")

class Bike(Vehicle):
    def ring(self) -> None:
        print("ring")

class Dog:
    def bark(self) -> None:
        print("woof!")


def move(v: Vehicle) -> None:
    v.move()

def instantiate(class_to_instantiate: Type[TVehicle]) -> TVehicle:
    return class_to_instantiate()  # create an instance

move(Bike())
move(Car())

instantiate(Bike).ring()
instantiate(Car).honk()
#instantiate(Dog)

CarBike继承自Vehicle,所以他们都至少得到了move方法和自定义__init__,这揭示了名字调用它的class。

现在,在第一个函数 move 中,我们只想指定参数 v 应该是 [=14] 的 实例 =].该函数调用 Vehiclemove 方法,该方法将显示发起调用的实例 class 的名称。

在第二个函数 instantiate 中,目标是创建一个 class 的实例。这通过 type variables 起作用,它允许您在此示例中指定函数的输入参数和输出参数之间存在关系:如果我要调用 instantiate(Bike),我想要 return 类型成为 Bike class 的一个实例,这样我就可以合法地调用它的 ring 方法。如果您只是简单地用 Vehicle 替换此函数定义中的 TVehicle,您的类型检查程序就会报错,因为 return 类型将成为 Vehicle 的实例class,您无法保证 ring 方法存在。 最后,您在 instantiate 的参数中看到的 Type 部分只允许您使用 class 调用函数,而不是使用 class 的实例。这很有用,例如在您想延迟实例化 class.

的情况下

请注意,这是一个说明如何操作的示例。在更专业的环境中,Vehicle 可能是 abstract base class,这里的一些方法可以作为 class 方法给出。

代码示例的旁注:

  1. 请注意,如果您不打算编写也适用于 Python2 的代码,则不应继承自 object (ref)。
  2. 类 通常用 CapWord 名称编写,如 specified in PEP8,Python 风格指南。遵循这种风格可以让您的代码更容易被其他开发人员理解。