Python - 如何传递给类对象的函数参数类型(打字)

Ser*_*sta 6 types arguments class function python-3.7

我想这是python 3.7(不确定)附带的,不仅可以将变量名传递给函数,还可以传递变量的类型。我想知道的是是否有可能传递特定类的类型。

你可以通过同样的方式:

def foo_func(i: int) -> None:
    pass
Run Code Online (Sandbox Code Playgroud)

如果我有一堂课,让我们说:

class foo_class(object):
    pass
Run Code Online (Sandbox Code Playgroud)

我怎样才能将 转换foo_func为接收foo_class而不是int类型?

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

class A(foo_class):
     pass

class B(foo_class):
     pass
Run Code Online (Sandbox Code Playgroud)

我怎么能通过AB基于它的父母?

我的意思是这样的:

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

foo_func(A())
foo_func(B())
Run Code Online (Sandbox Code Playgroud)

Oli*_* W. 10

根据您是要传递一个类(类型)还是一个类的实例,您要查找的要么是该类,要么typing.Type只是该类。

下面是一个简单的例子来解释这两种情况:

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)

Run Code Online (Sandbox Code Playgroud)

CarBike继承自Vehicle,因此它们都至少获得了move方法和自定义__init__,这揭示了调用它的类的名称。

现在,在第一个函数move,一个只是想指定的说法v应该是一个实例Vehicle。该函数调用Vehiclemove方法,该方法将显示发起调用的实例类的名称。

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

请注意,这是一个解释如何执行此操作的示例。在更专业的环境中,Vehicle可能是抽象基类,这里的某些方法可以作为类方法给出。

关于您的代码示例的旁注:

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