在基本情況下,可以輕松地將字典映射到引數。下面顯示了基本示例。
def func1(x: int, y: int):
return x y
input = {
"x": 1,
"y": 2,
}
## This Works
sum = func1(**input)
# sum = 3
Python 是否提供任何其他型別的快捷方式來為嵌套類啟用這種型別的行為?
from dataclasses import dataclass
@dataclass
class X:
x: int
@dataclass
class Y:
y: int
def func2(x: X, y: Y):
return x.x y.y
input_2 = {
"X": {
"x": 1,
},
"Y": {
"y": 1,
},
}
sum = func2(**input_2)
# TypeError: func2() got an unexpected keyword argument 'X'
我嘗試過其他方法。這是一個有效的例子,但不是很普遍。
sum = func2(X(input_2[X][x]),Y(input_2[Y][y])
pydantic 也失敗了
from pydantic import BaseModel
class X(BaseModel):
x: int
class Y(BaseModel):
y: int
def func2(x: X, y: Y):
return x.x y.y
input_2 = {
"X": {
"x": 1,
},
"Y": {
"y": 1,
},
}
sum = func2(**input_2)
uj5u.com熱心網友回復:
我認為創建一個包含Xand的新類Y,假設C可以適用于您的情況
from pydantic import BaseModel
class X(BaseModel):
x: int
class Y(BaseModel):
y: int
class C(X, Y):
pass
def func2(c: C):
x = c.x
y = c.y
return x y
input_2 = C(**{
"x": 1,
"y": 1,
})
sum = func2(input_2)
print(sum)
uj5u.com熱心網友回復:
您可以使用裝飾器將dict函式引數的每個引數轉換為其帶注釋的型別,假設在這種情況下型別是 adataclass或 a BaseModel。
帶有 - 的示例dataclass-wizard也應該支持嵌套資料類模型:
import functools
from dataclasses import dataclass, is_dataclass
from dataclass_wizard import fromdict
def transform_dict_to_obj(f):
name_to_tp = {name: tp for name, tp in f.__annotations__.items()
if is_dataclass(tp)}
@functools.wraps(f)
def new_func(**kwargs):
for name, tp in name_to_tp.items():
if name in kwargs:
kwargs[name] = fromdict(tp, kwargs[name])
return f(**kwargs)
return new_func
@dataclass
class X:
x: int
@dataclass
class Y:
y: int
@transform_dict_to_obj
def func2(*, x: X, y: Y) -> str:
return x.x y.y
input_2 = {
"x": {
"x": 1,
},
"y": {
"y": 1,
},
}
sum = func2(**input_2)
print('Sum:', sum)
assert sum == 2 # OK
同樣,使用pydantic:
import functools
from pydantic import BaseModel
class X(BaseModel):
x: int
class Y(BaseModel):
y: int
def transform_dict_to_obj(f):
name_to_from_dict = {name: tp.parse_obj
for name, tp in f.__annotations__.items()
if issubclass(tp, BaseModel)}
@functools.wraps(f)
def new_func(**kwargs):
for name, from_dict in name_to_from_dict.items():
if name in kwargs:
kwargs[name] = from_dict(kwargs[name])
return f(**kwargs)
return new_func
@transform_dict_to_obj
def func2(*, x: X, y: Y) -> str:
return x.x y.y
input_2 = {
"x": {
"x": 1,
},
"y": {
"y": 1,
},
}
sum = func2(**input_2)
print('Sum:', sum)
assert sum == 2 # OK
uj5u.com熱心網友回復:
@dataclass
class Math:
"""Collection of Configurations and Data Loading Utilities for PlayFab Churn Featurization"""
x: X
y: Y
@classmethod
def load(cls, config_json):
return Math(
x=X(**config_json['x']),
y=Y(**config_json['y']),
)
我想在建構式周圍,給自己一個不同的出路。我仍然可以獲得所有嵌套資料類的好處,保持與舊建構式的向后兼容性,并且仍然不需要 init 方法。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/439643.html
標籤:Python python-3.x 书呆子的 蟒蛇数据类
下一篇:使用PIL置換二進制掩碼中的像素
