Created
May 16, 2017 03:12
-
-
Save boredstiff/bac0ab0df0bec480c1fb0fd67eae0105 to your computer and use it in GitHub Desktop.
typing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from typing import (Dict, Tuple, List, NewType, Callable, Mapping, Sequence, TypeVar, Generic, | |
Iterable) | |
from logging import Logger | |
Vector = List[float] | |
def scale(scalar: float, vector: Vector) -> Vector: | |
return [scalar * num for num in vector] | |
new_vector = scale(2.0, [1.0, -4.2, 5.4]) | |
print('new_vector: {}'.format(new_vector)) | |
def greeting(name: str) -> str: | |
return 'Hello ' + name | |
print(greeting('Alex')) | |
# These are type aliases. | |
ConnectionOptions = Dict[str, str] | |
Address = Tuple[str, int] | |
Server = Tuple[Address, ConnectionOptions] | |
# Notice the Server in here. This is a type alias. | |
def broadcast_message(message: str, servers: List[Server]) -> None: | |
print(message) | |
print(servers) | |
# The previous type signature is exactly equivalent to this. | |
def broadcast_message_2(message: str, servers: List[Tuple[Tuple[str, int], Dict[str, str]]]) -> None: | |
print(message) | |
print(servers) | |
# Use NewType() to create distinct types | |
UserId = NewType('UserId', int) | |
some_id = UserId(542323) | |
# The static type checker will treat the new type as if it were a subclass of the original type. | |
# This is useful in catching logical errors. | |
def get_user_name(user_id: UserId) -> str: | |
return 'hello' | |
# typechecks | |
user_a = get_user_name(UserId(34234)) | |
# does not typecheck | |
user_b = get_user_name(-1) | |
# You can still perform all int operations on UserId, but the result will always be of type int. | |
# This means you can pass in a UserId wherever an int might be expected, but will prevent you from | |
# accidentally creating a UserId in an invalid way. | |
# output is int, not userId | |
output = UserId(23545) + UserId(757565) | |
UserId = NewType('UserId', int) | |
# Fails at runtime and does not typecheck | |
# class AdminUserId(UserId): pass | |
# Tells you that the function argument must be code, not str | |
# Also does not typecheck | |
ProUserId = NewType('ProUserId', UserId) | |
# The use of a type alias declares two types to be equivalent to one another. | |
# Doing Alias = Original will make the static type checker treat Alias as being exactly equivalent to Original | |
# in all cases. Useful for simplifying complex type signatures. | |
# NewType declares one type to be a subtype of another. | |
# NewType('A', B) Means A is a subclass of B. | |
# This means B cannot be used where A is expected. | |
def feeder(get_next_item: Callable[[], str]) -> None: | |
pass | |
def async_query(on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]) -> None: | |
pass | |
Employee = NewType('Employee', str) | |
# Generics | |
def notify_by_email(employees: Sequence[Employee], | |
overrides: Mapping[str, str]) -> None: | |
pass | |
# Generics can be parameterized by using a new factory available in typing called TypeVar. | |
T = TypeVar('T') # Declare type variable | |
def first(l: Sequence[T]) -> T: # Generic function | |
return l[0] | |
class LoggedVar(Generic[T]): | |
def __init__(self, value: T, name: str, logger: Logger) -> None: | |
self.name = name | |
self.logger = logger | |
self.value = value | |
def set(self, new: T) -> None: | |
self.log('Set ' + repr(self.value)) | |
self.value = new | |
def get(self) -> T: | |
self.log('Get ' + repr(self.value)) | |
return self.value | |
def log(self, message: str) -> None: | |
self.logger.info('%s: %s', self.name, message) | |
# Generic base class uses a metaclass that defines __getitem__ so that LoggedVar[t] is valid as a type | |
def zero_all_vars(vars: Iterable[LoggedVar[int]]) -> None: | |
for var in vars: | |
var.set(0) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment