Dataclasses and property decorator

前端 未结 10 1666
没有蜡笔的小新
没有蜡笔的小新 2020-12-15 04:43

I\'ve been reading up on Python 3.7\'s dataclass as an alternative to namedtuples (what I typically use when having to group data in a structure). I was wondering if datacla

10条回答
  •  醉酒成梦
    2020-12-15 05:01

    Some wrapping could be good:

    # Copyright 2019 Xu Siyuan
    # 
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    # 
    # http://www.apache.org/licenses/LICENSE-2.0
    # 
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License. 
    
    from dataclasses import dataclass, field
    
    MISSING = object()
    __all__ = ['property_field', 'property_dataclass']
    
    
    class property_field:
        def __init__(self, fget=None, fset=None, fdel=None, doc=None, **kwargs):
            self.field = field(**kwargs)
            self.property = property(fget, fset, fdel, doc)
    
        def getter(self, fget):
            self.property = self.property.getter(fget)
            return self
    
        def setter(self, fset):
            self.property = self.property.setter(fset)
            return self
    
        def deleter(self, fdel):
            self.property = self.property.deleter(fdel)
            return self
    
    
    def property_dataclass(cls=MISSING, / , **kwargs):
        if cls is MISSING:
            return lambda cls: property_dataclass(cls, **kwargs)
        remembers = {}
        for k in dir(cls):
            if isinstance(getattr(cls, k), property_field):
                remembers[k] = getattr(cls, k).property
                setattr(cls, k, getattr(cls, k).field)
        result = dataclass(**kwargs)(cls)
        for k, p in remembers.items():
            setattr(result, k, p)
        return result
    

    You can use it like this:

    @property_dataclass
    class B:
        x: int = property_field(default_factory=int)
    
        @x.getter
        def x(self):
            return self._x
    
        @x.setter
        def x(self, value):
            self._x = value
    

提交回复
热议问题