簡體   English   中英

當屬性不遵守命名規則時python中的數據類

[英]Dataclass in python when the attribute doesn't respect naming rules

如果您有這樣的數據(來自 yaml 文件):

items:
  C>A/G>T: "#string"
  C>G/G>C: "#string"
  ...

如何將其加載到明確說明其鍵和類型的數據類中? 理想情況下,我會:

@dataclasses.dataclass
class X:
    C>A/G>T: str
    C>G/G>C: str
...

更新:

SBS_Mutations = TypedDict(
    "SBS_Mutations",
    {
        "C>A/G>T": str,
        "C>G/G>C": str,
        "C>T/G>A": str,
        "T>A/A>T": str,
        "T>C/A>G": str,
        "T>G/A>C": str,
    },
)

my_data = {....}

SBS_Mutations(my_data) # not sure how to use it here

如果您想要這樣的符號,它們顯然不能是 Python 標識符,然后,想要使用具有屬性訪問權限的數據類為您提供的設施是沒有意義的。

只需將您的數據保存在字典或 Pandas 數據框中,這些名稱可以是列標題。

否則,發布一個適當的代碼片段,其中包含您從何處獲取數據的最小示例,然后,可以添加一個答案,一個將您的原始名稱轉換為有效 Python 屬性名稱的適當位置,並幫助構建一個動態的數據類。

這聽起來像是我最近發布的dotwiz庫的一個很好的用例。 這提供了一個dict子類,它為嵌套鍵啟用屬性樣式點訪問。

在最近的版本中,它提供了一個DotWizPlus實現(一個dict對象的包裝器),它還對鍵進行大小寫轉換,以便它們是有效的小寫 Python 標識符名稱,如下所示。

# requires the following dependencies:
#   pip install PyYAML dotwiz
import yaml
from dotwiz import DotWizPlus

yaml_str = """
items:
  C>A/G>T: "#string"
  C>G/G>C: "#string"
"""

yaml_dict = yaml.safe_load(yaml_str)
print(yaml_dict)

dw = DotWizPlus(yaml_dict)
print(dw)

assert dw.items.c_a_g_t == '#string'  # True

print(dw.to_attr_dict())

輸出:

{'items': {'C>A/G>T': '#string', 'C>G/G>C': '#string'}}
✪(items=✪(c_a_g_t='#string', c_g_g_c='#string'))
{'items': {'c_a_g_t': '#string', 'c_g_g_c': '#string'}}

注意:目前DotWiz實例訪問鍵items時會失敗,因為鍵名與內置屬性dict.items()沖突。 我目前已經提交了一個錯誤請求,並希望特別能解決這個邊緣案例。

類型提示

如果您想要字段名稱的類型提示或自動建議,您可以嘗試這樣的方法,您可以從DotWizPlus子類化:

import yaml
from dotwiz import DotWizPlus


class Item(DotWizPlus):
    c_a_g_t: str
    c_g_g_c: str

    @classmethod
    def from_yaml(cls, yaml_string: str, loader=yaml.safe_load):
        yaml_dict = loader(yaml_str)
        return cls(yaml_dict['items'])


yaml_str = """
items:
  C>A/G>T: "#string1"
  C>G/G>C: "#string2"
"""

dw = Item.from_yaml(yaml_str)
print(dw)
# ✪(c_a_g_t='#string1', c_g_g_c='#string2')

assert dw.c_a_g_t == '#string1'  # True

# auto-completion will work, as IDE knows the type is a `str`
# dw.c_a_g_t.

數據類

如果您仍然希望將數據類用於類型提示,您還可以查看另一個名為dataclass-wizard 的庫,它也可以幫助簡化此任務。

更具體地說, YAMLWizard使使用 YAML 加載/轉儲類對象變得更加容易。 請注意,默認情況下,這會在后台使用PyYAML庫。

請注意,在這種情況下,我無法讓 case-transform 工作,因為我猜這是底層to_snake_case()實現中的一個錯誤。 我還將提交一個錯誤請求來調查這個邊緣案例。 但是,現在如果更明確地指定 YAML 中的鍵名,它應該可以工作:

from dataclasses import dataclass

from dataclass_wizard import YAMLWizard, json_field

yaml_str = """
items:
  C>A/G>T: "#string"
  C>G/G>C: "#string"
"""


@dataclass
class Container(YAMLWizard):
    items: 'Item'


@dataclass
class Item:
    c_a_g_t: str = json_field('C>A/G>T')
    c_g_g_c: str = json_field('C>G/G>C')


c = Container.from_yaml(yaml_str)
print(c)

# True
assert c.items.c_g_g_c == c.items.c_a_g_t == '#string'

輸出:

Container(items=Item(c_a_g_t='#string', c_g_g_c='#string'))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM