您的首要任务应该是创建一个新的数据类型来表示允许的字典键。
让我们假设新的数据类型被命名为Country
from enum import Enum, auto
class Country(Enum):
def _generate_next_value_(name, start, count, last_values):
return name
RUSSIA = auto()
CHINA = auto()
UNITED_STATES = auto()
AUSTRALIA = auto()
BRAZIL = auto()
让我们看一些例子:
example1 = Country("UNITED_STATES")
example2 = Country("RUSSIA")
print("str(example1)".ljust(20), " == ", str(example1))
print("repr(example1)".ljust(20), " == ", repr(example1))
print("example2".ljust(20), " == ", example2)
print("example1.value".ljust(20), " == ", example1.value)
print("example1.name".ljust(20), " == ", example1.name)
打印到控制台的输出如下:
str(example1) == Country.UNITED_STATES
repr(example1) == <Country.UNITED_STATES: 'UNITED_STATES'>
example2 == Country.RUSSIA
example1.value == UNITED_STATES
example1.name == UNITED_STATES
通常,枚举数据类型是整数。
例如RUSSIA == 41
.
然而,使用字符串更具自记录性。
请随意使用枚举数据类型以外的其他类型(enum
)。目标只是创建一个类来表示允许的字典键。
下面是一个实现not枚举数据类型:
import string
class Kountry:
BRAZIL = "BRAZIL"
CHINA = "CHINA"
UNITED_STATES = "UNITED_STATES"
def __init__(this, dirty_stryng:str):
stryng = "".join(str(ch) for ch in dirty_stryng)
stryng = stryng.upper()
is_letter = lambda ch: ch in string.ascii_uppercase
stryng = "".join(filter(is_letter, stryng))
if not stryng in type(this).COUNTRIES:
# print invalid input
# maximum 30 characters. do not print 9,000 characters
# remove line-breaks, carriage returns etc...
# string representation of invalid input must fit all on one line
msg = repr(str(dirty_stryng))[:30]
raise ValueError(msg)
this._string = stryng
def __getattr__(this, attrname:str):
if has_attr(this._string, attrname):
return getattr(this._string, attrname)
return getattr(type(this), attrname)
def __str__(this):
return this._string
我们可以把这个非enum
出去转转:
brazil = Kountry("brazil")
r = str(brazil)
print("str(brazil)".ljust(20), " is ", r)
r = brazil.split()
print("brazil.split()".ljust(20), " is ", r)
r = brazil.join("$-@")
print("brazil.join(\"$-@\")".ljust(20), " is ", r)
控制台输出为:
str(brazil) is BRAZIL
brazil.split() is ['BRAZIL']
brazil.join("$-@") is $BRAZIL-BRAZIL@
定义一个名为“的新数据类型后Country
”,然后您需要执行以下操作:
-
定义函数,其输入参数必须是Country
class.
-
创建一个字典,其键必须是Country
class.
我们可以创建一个函数,其参数应该是 Country 类的实例,如下所示:
def to_pretty_string(cntry:Country):
country_str = str(cntry.name)
out_str = "-xXx-".join(["", country_str, ""])
return out_str
我写的地方:Country
在输入参数上...那是一个 python ”类型提示". The 类型提示表示函数参数应该是Country
class.
如果您好奇,当我们调用(使用)时,我们会在控制台上输出以下内容to_pretty_string
功能:
print(to_pretty_string(Country.BRAZIL))
print(to_pretty_string(Country.UNITED_STATES))
print(to_pretty_string(Country.RUSSIA))
# -xXx-BRAZIL-xXx-
# -xXx-UNITED_STATES-xXx-
# -xXx-RUSSIA-xXx-
用像这样的语言C++,我们会使用“模板类” 字典中。Java,它们被称为“泛型”而不是“模板”。但是,无论称为“模板类”还是“泛型类”,都是相同的概念
我希望以下是真实的代码:
# WARNING: this is not real python
# Create a dictionary whose keys are Countries
head_counts = Dict[Country]
# Populate the dictionary
head_counts[Country.UNITED_STATES] = 329.5*1000000
head_counts[Country.RUSSIA] = 144.1*1000000
head_counts[Country.BRAZIL] = 212.6*1000000
# End of wishful thinking
然而,Python 编程语言在其标准库中并没有太多通用类的方式。您可能必须编写自己的类才能拥有仅包含字符串键的字典(Dict[str]
) 或键仅为十进制数字的字典 (Dict[float]
)
我们能做的就是创建一个类型提示.
但是,那类型提示不创建真正的字典;仅在参数列表中使用一个特殊对象来指定该对象可能应该是一个字典,其键是 Country:
import typing as typ
import Country
def funky_the_function(dee:typ.Dict[Country, object]):
print("Keys to `dee` should be instances of `Country`")
dee[Country.UNITED_STATES] = 329.5*1000000
dee[Country.RUSSIA] = 144.1*1000000
dee[Country.BRAZIL] = 212.6*1000000
dee[342] # Danger Will Robinson! Danger!
return