你如何在python中对一个类型进行别名?

时间:2015-10-09 18:47:59

标签: python alias

在某些(主要是功能性)语言中,您可以执行以下操作:

type row = list(datum)

type row = [datum]

这样我们就可以构建这样的东西:

type row = [datum]
type table = [row]
type database = [table]

有没有办法在python中执行此操作?你可以使用类来完成它,但是python有很多功能方面,所以我想知道它是否可以更容易地完成。

4 个答案:

答案 0 :(得分:25)

从Python 3.5开始,您可以使用typing模块。

引用文档, 通过将类型分配给别名来定义类型别名:

Vector = List[float]

要了解有关在Python中强制执行类型的详细信息,您可能需要熟悉PEP:PEP483PEP484

Python历史上一直使用duck-typing而不是强类型,并且在3.5版本发布之前没有内置的强制类型的方式。

答案 1 :(得分:2)

@Lukasz 接受的答案是我们大部分时间都需要的。但是对于您需要别名单独成为不同类型的情况,您可能需要使用 typing.NewType,如此处所述:https://docs.python.org/3/library/typing.html#newtype

from typing import List, NewType

Vector = NewType("Vector", List[float])

一个特殊用例是,如果您使用 injector 库并且需要注入别名新类型而不是原始类型。

from typing import NewType

from injector import inject, Injector, Module, provider

AliasRawType = str
AliasNewType = NewType("AliasNewType", str)


class MyModule(Module):
    @provider
    def provide_raw_type(self) -> str:
        return "This is the raw type"

    @provider
    def provide_alias_raw_type(self) -> AliasRawType:
        return AliasRawType("This is the AliasRawType")

    @provider
    def provide_alias_new_type(self) -> AliasNewType:
        return AliasNewType("This is the AliasNewType")


class Test1:
    @inject
    def __init__(self, raw_type: str):  # Would be injected with MyModule.provide_raw_type() which is str. Expected.
        self.data = raw_type


class Test2:
    @inject
    def __init__(self, alias_raw_type: AliasRawType):  # Would be injected with MyModule.provide_raw_type() which is str and not MyModule.provide_alias_raw_type() which is just a direct alias to str. Unexpected.
        self.data = alias_raw_type


class Test3:
    @inject
    def __init__(self, alias_new_type: AliasNewType): # Would be injected with MyModule.provide_alias_new_type() which is a distinct alias to str. Expected.
        self.data = alias_new_type


injector = Injector([MyModule()])
print(injector.get(Test1).data, "-> Test1 injected with str")
print(injector.get(Test2).data, "-> Test2 injected with AliasRawType")
print(injector.get(Test3).data, "-> Test3 injected with AliasNewType")

输出:

This is the raw type -> Test1 injected with str
This is the raw type -> Test2 injected with AliasRawType
This is the AliasNewType -> Test3 injected with AliasNewType

因此,要在使用 injector 库时正确注入正确的提供程序,您需要使用 NewType 别名。

答案 2 :(得分:-1)

Python是动态类型的。虽然ŁukaszR。的答案对于类型提示目的是正确的(可以反过来用于静态分析和linting),严格地说,你不需要做任何事情来完成这项工作。只需构建这样的列表并将它们分配给变量:

foo_table = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
bar_table = ...
foo_database = [foo_table, bar_table, ...]

类型提示确实非常有用,因为它们可以帮助记录代码的行为方式,并且可以在静态和运行时对它们进行检查。但是,如果不方便,强制你就不会这样做。

答案 3 :(得分:-2)

row = lambda datum: list(datum)之类的内容怎么样?没有真正的类型内省支持,但它是一种非常简单的“别名”类型方式,因为Python对鸭子类型的喜爱。它功能齐全!有点。