Python - 如何传递给类对象的函数参数类型(打字) [英] Python - how to pass to a function argument type of a class object (typing)

查看:24
本文介绍了Python - 如何传递给类对象的函数参数类型(打字)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I suppose that came with python 3.7 (not sure), the possibility to pass to a function not only the variable name but also the type of the variable. What I would like to know is if there is any possibility of passing the type of a particular class.

你可以通过同样的方式:

The same way you could pass:

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

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

If I have a class let's say:

class foo_class(object):
    pass

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

How could I transform the foo_func to receive the foo_classinstead of the inttype?

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

Furthermore, if foo_class was an inheritance of another class could I impose a more general type from the parent? For instance, if I would have,

class A(foo_class):
     pass

class B(foo_class):
     pass

我如何根据其父项传递 AB ?

How could I pass A or B based on its parent?

我的意思是:

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

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

推荐答案

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

Depending on whether you meant to pass a class (type) or an instance of a class, you’re looking for either typing.Type or simply the class.

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

Here’s a simple example to explain both situations:

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__,显示调用它的类的名称.

Car and Bike inherit from Vehicle, so they both get at least the move method and the custom __init__, which reveals the name of the class that invoked it.

现在,在第一个函数 move 中,我们只想指定参数 v 应该是 v实例>车辆.该函数调用 Vehiclemove 方法,该方法将显示发起调用的实例类的名称.

Now, in the first function, move, one simply wants to specify that the argument v should be an instance of a Vehicle. The function calls Vehicle’s move method, which will reveal the name of the instance’s class from which the call originated.

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

In the second function, instantiate, the goal is to create an instance of a class. This works through type variables, which allow you in this example to specify that there’s a relation between the function’s input argument and output argument: if I were to call instantiate(Bike), I want the return type to be an instance of the Bike class, so that I may legally call its ring method. If you were to replace the TVehicle in this function definition simply by Vehicle, your type checking program would complain, because the return type would then be an instance of the Vehicle class, for which you do not have a guarantee that the ring method exists. Finally, the Type part that you see in the argument of instantiate simply allows you to call the function with a class, so not with an instance of that class. This is useful e.g. in cases where you want to delay instantiation of a class.

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

Note that this is an example to explain how to do it. In a more professional setting, Vehicle would likely be an abstract base class and some methods here could be given as class methods.

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

Side notes on your code example:

  1. 请注意,如果您不打算编写也适用于 Python2 的代码,则不应从 object (参考).
  2. 类通常使用 CapWord 名称编写,如 在 PEP8 中指定,Python 风格指南.遵循这种风格可以让其他开发者更容易理解您的代码.
  1. Note that if you don’t intend to write code that also works in Python2, you shouldn’t inherit from object (ref).
  2. Classes are typically written with CapWord names, as specified in PEP8, the Python style guide. Following this style makes your code more easily understandable by other developers.

这篇关于Python - 如何传递给类对象的函数参数类型(打字)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆