You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyYAML解析自定义MyClass类时数组数据为空问题修复

Fixing Empty Numpy Arrays When Deserializing MyClass with PyYAML

Let's break down why your numpy arrays are coming up empty during deserialization and fix this step by step. The core issues almost always boil down to how you handle private attributes, numpy array serialization, and mapping between your class and YAML's data format.

Common Root Causes

  1. Private attributes weren't included in the serialized data: Your _T and _zeros are private (single-underscore) attributes—PyYAML won't auto-include them, so you have to explicitly add them to your serialization dictionary.
  2. Numpy arrays weren't converted to YAML-friendly types: PyYAML doesn't natively understand numpy.ndarray objects. If you try to serialize them directly, you'll get unparseable output or missing data.
  3. Deserialization didn't convert back to numpy arrays: Even if you wrote the arrays as lists, you need to explicitly convert those lists back to numpy.ndarray when reconstructing your class instance.
  4. Shallow mapping during deserialization: Forgetting deep=True in construct_mapping can leave nested structures (like 2D arrays) unparsed, appearing as empty containers.

Fixed Implementation

Here's the corrected code that addresses all these issues:

import yaml
import numpy as np

class MyClass:
    def __init__(self, name, T, zeros):
        self.name = name
        self._T = T  # Private numpy array
        self._zeros = zeros  # Private numpy array

    def toDict(self):
        # Explicitly include private attributes, convert numpy arrays to lists
        return {
            "name": self.name,
            "_T": self._T.tolist(),
            "_zeros": self._zeros.tolist()
        }

    # Custom serializer for PyYAML
    def to_yaml(self, dumper):
        return dumper.represent_mapping("!MyClass", self.toDict())

    # Custom deserializer for PyYAML
    @classmethod
    def from_yaml(cls, loader, node):
        # Deep parse the YAML node to get all nested data
        mapping = loader.construct_mapping(node, deep=True)
        # Convert lists back to numpy arrays and reconstruct the instance
        return cls(
            name=mapping["name"],
            T=np.array(mapping["_T"]),
            zeros=np.array(mapping["_zeros"])
        )

# Register the serializer and deserializer with PyYAML
yaml.add_representer(MyClass, MyClass.to_yaml)
yaml.add_constructor("!MyClass", MyClass.from_yaml)

# Test the implementation
if __name__ == "__main__":
    # Create a test instance
    test_obj = MyClass(
        name="demo",
        T=np.array([[1, 2], [3, 4]]),
        zeros=np.zeros((2, 3))
    )

    # Write to YAML file
    with open("myclass.yaml", "w") as f:
        yaml.dump(test_obj, f)

    # Read back from YAML file
    with open("myclass.yaml", "r") as f:
        loaded_obj = yaml.load(f, Loader=yaml.FullLoader)

    # Verify the data is intact
    print(f"Name: {loaded_obj.name}")
    print(f"_T array:\n{loaded_obj._T}")
    print(f"_zeros array:\n{loaded_obj._zeros}")

Key Fixes Explained

  1. Explicit private attribute inclusion: The toDict method now explicitly adds _T and _zeros to the serialization dictionary—no more missing data in the YAML file.
  2. Numpy ↔ List conversion: We use tolist() to convert numpy arrays to native Python lists for YAML compatibility, then np.array() to convert them back during deserialization.
  3. Deep mapping: The deep=True flag in construct_mapping ensures nested structures (like multi-dimensional arrays) are fully parsed, not just left as empty placeholders.
  4. Consistent key names: We use the exact same keys (_T, _zeros) in both serialization and deserialization to avoid mismatches.

Quick Troubleshooting Checklist

If you still run into issues:

  1. Open your YAML file and check if _T and _zeros are present—if not, your toDict or to_yaml method isn't including them.
  2. Ensure you're using the correct loader (e.g., FullLoader instead of the deprecated Loader).
  3. Double-check that your constructor is using the same key names as your serializer.

内容的提问来源于stack exchange,提问作者gt6989b

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:54:38