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

时间:2019-04-18 17:52:18

标签: function class types arguments python-3.7

我想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

如何根据其父项传递AB

我的意思是:

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

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

1 个答案:

答案 0 :(得分:2)

根据要传递类(类型)还是要传递类的实例,您在寻找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)

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

现在,在第一个函数move中,人们只想指定参数v应该是Vehicle instance 。该函数调用Vehicle的{​​{1}}方法,该方法将显示调用源于的实例类的名称。

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

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

您的代码示例的旁注:

  1. 请注意,如果您不打算编写在Python2中也可以使用的代码,则不应继承自Vehicleref)。
  2. 类通常以object的名称编写,如specified in PEP8,Python样式指南。遵循这种样式可使您的代码更容易为其他开发人员所理解。