Python - 如何传递给类对象的函数参数类型(键入)[重复]

问题描述 投票:0回答:1

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

以同样的方式通过:

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

如果我有课,我们可以说:

class foo_class(object):
    pass

如何转换

foo_func
来接收
foo_class
而不是
int
类型?

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

class A(foo_class):
     pass

class B(foo_class):
     pass

我如何根据其父级传递

A
B

我的意思是:

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

foo_func(A())
foo_func(B())
python class python-3.7 python-typing
1个回答
33
投票

根据您是要传递类(类型)还是类的实例,您正在寻找

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)

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

现在,在第一个函数

move
中,我们只想指定参数
v
应该是 Vehicle
实例
。该函数调用
Vehicle
move
方法,该方法将显示发起调用的实例类的名称。

在第二个函数

instantiate
中,目标是创建类的实例。这是通过 类型变量 实现的,它允许您在此示例中指定函数的输入参数和输出参数之间存在关系:如果我要调用
instantiate(Bike)
,我希望返回类型是
 的实例Bike
类,这样我就可以合法地调用它的
ring
方法。如果您仅用
TVehicle
替换此函数定义中的
Vehicle
,您的类型检查程序会抱怨,因为返回类型将是
Vehicle
类的实例,而您对此没有保证
ring
方法存在。 最后,您在
Type
的参数中看到的
instantiate
部分仅允许您使用类来调用函数,而不是使用该类的实例。这很有用,例如如果您想延迟类的实例化。

请注意,这是一个解释如何操作的示例。在更专业的环境中,

Vehicle
可能是一个抽象基类,这里的一些方法可以作为类方法给出。

代码示例的旁注:

  1. 请注意,如果您不打算编写也适用于 Python2 的代码,则不应继承自
    object
    (ref)。
  2. 类通常使用
    CapWord
    名称编写,如 Python 风格指南 PEP8 中所指定。遵循这种风格可以使您的代码更容易被其他开发人员理解。
© www.soinside.com 2019 - 2024. All rights reserved.