处理 mypy
@overload
我想要类似 enum
的东西,但是针对类型。
你看,我处理
mpi4py
并且有一个参数 tag
没有做任何有用的事情,只是分隔消息(以便接收者可以知道它是什么数据)。
使用不同的标签,我发送不同的数据、数据类型,但代码编辑器甚至不会检查它,如果我不小心发送带有错误标签的数据,我可能会感到困惑。
我的计划是定义一个特殊的函数来发送数据
from typing import Tuple, Dict, Union, overload
from mpi4py import MPI
MPIComm = Union[MPI.Intracomm, MPI.Intercomm]
class TAG_NUMERIC:
tag = 1
class TAG_STRING
tag = 2
class TAG_DICT_STR_INT:
tag = 3
class TAG_DICT_STR_TUPLE_INT_INT:
tag = 4
@overload
def send(mpi_comm: MPIComm, dest: int, data: int, tag: TAG_NUMERIC) -> None: ...
@overload
def send(mpi_comm: MPIComm, dest: int, data: str, tag: TAG_STRING -> None: ...
@overload
def send(mpi_comm: MPIComm, dest: int, data: Dict[str, int], tag: TAG_DICT_STR_INT) -> None: ...
@overload
def send(mpi_comm: MPIComm, dest: int, data: Dict[str, Tuple[int, int]], tag: TAG_DICT_STR_TUPLE_INT_INT) -> None: ...
def send(mpi_comm, data, dest, tag):
mpi_comm.send(obj=data dest=dest, tag=tag)
这样称呼它:
some_int = 5
send(mpi_comm, 1, some_int, TAG_NUMERIC.tag)
some_string = 'abcd'
send(mpi_comm, 1, some_string, TAG_STRING.tag)
some_simple_dict = {"key1": 1, "key2": 2}
send(mpi_comm, 1, some_simple_dict, TAG_DICT_STR_INT.tag)
some_advanced_dict = {"key1": (1, 2), "key2": (3, 4)}
send(mpi_comm, 1, some_advanced_dict, TAG_DICT_STR_TUPLE_INT_INT.tag)
但是写这么多行只是为了在类名中定义一个对应类型的另一个类型实在是太“不聪明”了。
有没有可能的方法来定义类似
enum
的东西,但对于类型(类),这些类将只包含一个常量?类似的东西
class TAGS(int, typeEnum):
HOUSE_NUMBER = 1 # corresponding data type: int
STREET_NAME = 2 # corresponding data type: str
NAMES_AND_AGES = 3 # corresponding data type: Dict[str, int]
SOMETHING = 4 # corresponding data type: Dict[str, Tuple[int, int]]
并使用它
var = TAGS.SOMETHING.value
print(var) # output: 4
type(var) # output: TAGS.SOMETHING
您可以使用
type()
动态定义类。所以,你可以这样做。
from enum import IntEnum
class TAG(IntEnum):
NUMERIC = 1
STRING = 2
for k, v in TAG.__members__.items():
name = 'TAG_' + k
globals()[name] = type(name, (), dict(tag=v.value))
print(TAG_NUMERIC, TAG_NUMERIC.tag)
# This will print "<class '__main__.TAG_NUMERIC'> 1".