2011-08-25 9 views
6

Tôi muốn có một hàm tùy chỉnh nối tiếp các đối tượng python tùy ý, như cách hàm json.dump có một tham số tùy chọn được gọi là 'mặc định', đó phải là một hàm mà jumper dumper sẽ gọi nếu đối tượng không phải là tuần tự json.Làm cách nào để viết một người gửi lại cho PyYAML?

Tôi chỉ muốn làm tương đương với điều này từ gói json.

json.dump(tests_dump, file('somefile', 'w+'), default = lambda x: x.__dict__) 

Dường như tôi cần phải viết yaml.add_representer, từ các tài liệu PyYAML, nhưng nó thực sự là không rõ ràng làm thế nào để làm điều này.

Trả lời

3

Đây là mẫu cho add_representer. Không chắc chắn nếu điều này là chính xác những gì bạn muốn. Tuy nhiên ...

import yaml 

#Arbitrary Class 
class MyClass: 
    def __init__(self, someNumber, someString): 
    self.var1 = someNumber 
    self.var2 = someString 

#define the representer, responsible for serialization 
def MyClass_representer(dumper, data): 
    serializedData = str(data.var1) + "|" + data.var2 
    return dumper.represent_scalar('!MyClass', serializedData) 

#'register' it  
yaml.add_representer(MyClass, MyClass_representer) 

obj = MyClass(100,'test') 

print ('original Object\nvar1:{0}, var2:{1}\n'.format(obj.var1, obj.var2)) 

#serialize 
yamlData = yaml.dump(obj) 

print('serialized as:\n{0}'.format(yamlData)) 

#Now to deserialize you need a constructor 
def MyClass_constructor(loader,node): 
    value = loader.construct_scalar(node) 
    someNumber,sep,someString = value.partition("|") 
    return MyClass(someNumber,someString) 

#'register' it  
yaml.add_constructor('!MyClass', MyClass_constructor) 

#deserialize 
obj2 = yaml.load(yamlData) 

print ('after deserialization\nvar1:{0}, var2:{1}\n'.format(obj2.var1, obj2.var2)) 

Tất nhiên có mã trùng lặp và mã không được tối ưu hóa. Bạn có thể làm cho hai chức năng này trở thành một phần của Class của bạn và cũng có thể triển khai __repr__ để có được một đại diện có thể in mà bạn có thể sử dụng để điền serializedData vào MyClass_representer

+0

làm cách nào để 'hủy đăng ký'. Tôi làm việc trong môi trường có các công cụ khác dựa vào hành vi khác nhau, tôi thấy rằng nếu tôi thêm representer và constructor như thế này, nó sẽ thay đổi hành vi của mô đun yaml, ngay cả khi mã được gọi là yaml nằm trong một tệp khác mô-đun. – Shuman

+0

Làm cách nào để thực hiện công việc này cho một hệ thống phân cấp các lớp (nói A (roor), B (root), C (root))? –