Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you alias a type in Python?

In some (mostly functional) languages you can do something like this:

type row = list(datum) 

or

type row = [datum] 

So that we can build things like this:

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

Is there a way to do this in Python? You could do it using classes, but Python has quite some functional aspects so I was wondering if it could be done an easier way.

like image 481
Lara Avatar asked Oct 09 '15 18:10

Lara


People also ask

What is a type alias Python?

A type alias is defined by assigning the type to the alias. In this example, Vector and list[float] will be treated as interchangeable synonyms: Vector = list[float] def scale(scalar: float, vector: Vector) -> Vector: return [scalar * num for num in vector] # typechecks; a list of floats qualifies as a Vector.

How do I create an alias in Python?

You can use echo alias python=python3 >> . zshrc and echo alias pip=pip3 >> . zshrc . If you use bash instead of zsh then just replace .

What is a type alias?

A type alias allows you to provide a new name for an existing data type into your program. After a type alias is declared, the aliased name can be used instead of the existing type throughout the program. Type alias do not create new types. They simply provide a new name to an existing type.

How do you define a type in Python?

Specify a Variable Type Casting in python is therefore done using constructor functions: int() - constructs an integer number from an integer literal, a float literal (by rounding down to the previous whole number), or a string literal (providing the string represents a whole number)


2 Answers

Since Python 3.5 you may use typing module.

Quoting docs, A type alias is defined by assigning the type to the alias:

Vector = List[float] 

To learn more about enforcing types in Python you may want to get familiar with PEPs: PEP483 and PEP484.

Python historically was using duck-typing instead of strong typing and hadn't built-in way of enforcing types before 3.5 release.

like image 152
Łukasz Rogalski Avatar answered Sep 20 '22 18:09

Łukasz Rogalski


The accepted answer from @Lukasz is what we would need for most of the time. But for cases where you need the alias to be a distinct type on its own, you might need to use typing.NewType as documented here: https://docs.python.org/3/library/typing.html#newtype

from typing import List, NewType  Vector = NewType("Vector", List[float]) 

One particular use case is if you are using the injector library and you need to inject the aliased new type rather than the original type.

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") 

Output:

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 

Thus to correctly inject the proper provider when using the injector library, you would need the NewType aliasing.

like image 29
Niel Godfrey Ponciano Avatar answered Sep 23 '22 18:09

Niel Godfrey Ponciano