假设我有以下代码用于处理个人和国家之间的链接:
from dataclasses import dataclass
@dataclass
class Country:
iso2 : str
iso3 : str
name : str
countries = [ Country('AW','ABW','Aruba'),
Country('AF','AFG','Afghanistan'),
Country('AO','AGO','Angola')]
countries_by_iso2 = {c.iso2 : c for c in countries}
countries_by_iso3 = {c.iso3 : c for c in countries}
@dataclass
class CountryLink:
person_id : int
country : Country
country_links = [ CountryLink(123, countries_by_iso2['AW']),
CountryLink(456, countries_by_iso3['AFG']),
CountryLink(789, countries_by_iso2['AO'])]
print(country_links[0].country.name)
这一切都很好,但我决定,我想让它不那么笨重,能够处理不同形式的输入。我还想使用__new__
来确保每次都得到一个有效的ISO代码,并且我希望在这种情况下创建一个失败的对象。因此,我添加了两个新类,它们继承自:
@dataclass
class CountryLinkFromISO2(CountryLink):
def __new__(cls, person_id : int, iso2 : str):
if iso2 not in countries_by_iso2:
return None
new_obj = super().__new__(cls)
new_obj.country = countries_by_iso2[iso2]
return new_obj
@dataclass
class CountryLinkFromISO3(CountryLink):
def __new__(cls, person_id : int, iso3 : str):
if iso3 not in countries_by_iso3:
return None
new_obj = super().__new__(cls)
new_obj.country = countries_by_iso3[iso3]
return new_obj
country_links = [ CountryLinkFromISO2(123, 'AW'),
CountryLinkFromISO3(456, 'AFG'),
CountryLinkFromISO2(789, 'AO')]
乍一看,这似乎有效,但后来我遇到了一个问题:
a = CountryLinkFromISO2(123, 'AW')
print(type(a))
print(a.country)
print(type(a.country))
返回:
<class '__main__.CountryLinkFromISO2'>
AW
<class 'str'>
继承的对象具有正确的类型,但其属性country
只是一个字符串,而不是我所期望的Country
类型。我在__new__
中放入了print语句,用于检查new_obj.country
的类型,并且在return
行之前是正确的
我想要实现的是使a
成为类型为CountryLinkFromISO2
的对象,该类型将继承我对CountryLink
所做的更改,并使其具有从字典countries_by_iso2
获取的属性country
。我怎样才能做到这一点
仅仅因为dataclass在幕后进行,并不意味着您的类没有
__init__()
。是的,看起来像:使用以下内容创建类时:
该
"AW"
字符串被传递给__init__()
,并将值设置为字符串以这种方式使用
__new__()
是脆弱的,并且从构造函数返回None是相当不符合pythonic(imo)的。也许您最好制作一个返回None
或所需类的实际工厂函数。那么你根本就不需要去处理__new__()
如果出于某种原因,需要使用
__new__()
,您可以在没有匹配项时从new返回None
,并在__post_init__()
中设置国家:您看到的行为是因为数据类在
__init__
中设置其字段,这发生在__new__
运行之后解决这个问题的Pythonic方法是提供一个替代构造函数。我不会做这些子类,因为它们只用于它们的构造函数
例如:
相关问题 更多 >
编程相关推荐