entity#

此模块提供可序列化、可验证、类型强制的领域对象和数据传输对象。它与 python Marshmallow 包有许多相同的动机。它与 Schematics 最为相似。

教程#

第 1 章:实体和字段基础知识#

>>> class Color(Enum):
...     blue = 0
...     black = 1
...     red = 2
>>> class Car(Entity):
...     weight = NumberField(required=False)
...     wheels = IntField(default=4, validation=lambda x: 3 <= x <= 4)
...     color = EnumField(Color)
>>> # create a new car object
>>> car = Car(color=Color.blue, weight=4242.46)
>>> car
Car(weight=4242.46, color=0)
>>> # it has 4 wheels, all by default
>>> car.wheels
4
>>> # but a car can't have 5 wheels!
>>> #  the `validation=` field is a simple callable that returns a
>>> #  boolean based on validity
>>> car.wheels = 5
Traceback (most recent call last):
ValidationError: Invalid value 5 for wheels
>>> # we can call .dump() on car, and just get back a standard
>>> #  python dict actually, it's an ordereddict to match attribute
>>> #  declaration order
>>> type(car.dump())
<class '...OrderedDict'>
>>> car.dump()
OrderedDict([('weight', 4242.46), ('wheels', 4), ('color', 0)])
>>> # and json too (note the order!)
>>> car.json()
'{"weight": 4242.46, "wheels": 4, "color": 0}'
>>> # green cars aren't allowed
>>> car.color = "green"
Traceback (most recent call last):
ValidationError: 'green' is not a valid Color
>>> # but black cars are!
>>> car.color = "black"
>>> car.color
<Color.black: 1>
>>> # car.color really is an enum, promise
>>> type(car.color)
<enum 'Color'>
>>> # enum assignment can be with any of (and preferentially)
>>> #   (1) an enum literal,
>>> #   (2) a valid enum value, or
>>> #   (3) a valid enum name
>>> car.color = Color.blue; car.color.value
0
>>> car.color = 1; car.color.name
'black'
>>> # let's do a round-trip marshalling of this thing
>>> same_car = Car.from_json(car.json())  # or equally Car.from_json(json.dumps(car.dump()))
>>> same_car == car
True
>>> # actually, they're two different instances
>>> same_car is not car
True
>>> # this works too
>>> cloned_car = Car(**car.dump())
>>> cloned_car == car
True
>>> # while we're at it, these are all equivalent too
>>> car == Car.from_objects(car)
True
>>> car == Car.from_objects({"weight": 4242.46, "wheels": 4, "color": 1})
True
>>> car == Car.from_json('{"weight": 4242.46, "color": 1}')
True
>>> # .from_objects() even lets you stack and combine objects
>>> class DumbClass:
...     color = 0
...     wheels = 3
>>> Car.from_objects(DumbClass(), dict(weight=2222, color=1))
Car(weight=2222, wheels=3, color=0)
>>> # and also pass kwargs that override properties pulled
>>> #  off any objects
>>> Car.from_objects(DumbClass(), {'weight': 2222, 'color': 1}, color=2, weight=33)
Car(weight=33, wheels=3, color=2)

第 2 章:实体和字段组合#

>>> # now let's get fancy
>>> # a ComposableField "nests" another valid Entity
>>> # a ListField's first argument is a "generic" type,
>>> #   which can be a valid Entity, any python primitive
>>> #   type, or a list of Entities/types
>>> class Fleet(Entity):
...     boss_car = ComposableField(Car)
...     cars = ListField(Car)
>>> # here's our fleet of company cars
>>> company_fleet = Fleet(boss_car=Car(color='red'), cars=[car, same_car, cloned_car])
>>> company_fleet.pretty_json()  
{
  "boss_car": {
    "wheels": 4
    "color": 2,
  },
  "cars": [
    {
      "weight": 4242.46,
      "wheels": 4
      "color": 1,
    },
    {
      "weight": 4242.46,
      "wheels": 4
      "color": 1,
    },
    {
      "weight": 4242.46,
      "wheels": 4
      "color": 1,
    }
  ]
}
>>> # the boss' car is red of course (and it's still an Enum)
>>> company_fleet.boss_car.color.name
'red'
>>> # and there are three cars left for the employees
>>> len(company_fleet.cars)
3

第 3 章:不可变性#

>>> class ImmutableCar(ImmutableEntity):
...     wheels = IntField(default=4, validation=lambda x: 3 <= x <= 4)
...     color = EnumField(Color)
>>> icar = ImmutableCar.from_objects({'wheels': 3, 'color': 'blue'})
>>> icar
ImmutableCar(wheels=3, color=0)
>>> icar.wheels = 4
Traceback (most recent call last):
AttributeError: Assignment not allowed. ImmutableCar is immutable.
>>> class FixedWheelCar(Entity):
...     wheels = IntField(default=4, immutable=True)
...     color = EnumField(Color)
>>> fwcar = FixedWheelCar.from_objects(icar)
>>> fwcar.json()
'{"wheels": 3, "color": 0}'
>>> # repainting the car is easy
>>> fwcar.color = Color.red
>>> fwcar.color.name
'red'
>>> # can't really change the number of wheels though
>>> fwcar.wheels = 18
Traceback (most recent call last):
AttributeError: The wheels field is immutable.

第 X 章:del 和 null 的杂草#

>>> old_date = lambda: isoparse('1982-02-17')
>>> class CarBattery(Entity):
...     # NOTE: default value can be a callable!
...     first_charge = DateField(required=False)  # default=None, nullable=False
...     latest_charge = DateField(default=old_date, nullable=True)  # required=True
...     expiration = DateField(default=old_date, required=False, nullable=False)
>>> # starting point
>>> battery = CarBattery()
>>> battery
CarBattery()
>>> battery.json()
'{"latest_charge": "1982-02-17T00:00:00", "expiration": "1982-02-17T00:00:00"}'
>>> # first_charge is not assigned a default value. Once one is assigned, it can be deleted,
>>> #   but it can't be made null.
>>> battery.first_charge = isoparse('2016-03-23')
>>> battery
CarBattery(first_charge=datetime.datetime(2016, 3, 23, 0, 0))
>>> battery.first_charge = None
Traceback (most recent call last):
ValidationError: Value for first_charge not given or invalid.
>>> del battery.first_charge
>>> battery
CarBattery()
>>> # latest_charge can be null, but it can't be deleted. The default value is a callable.
>>> del battery.latest_charge
Traceback (most recent call last):
AttributeError: The latest_charge field is required and cannot be deleted.
>>> battery.latest_charge = None
>>> battery.json()
'{"latest_charge": null, "expiration": "1982-02-17T00:00:00"}'
>>> # expiration is assigned by default, can't be made null, but can be deleted.
>>> battery.expiration
datetime.datetime(1982, 2, 17, 0, 0)
>>> battery.expiration = None
Traceback (most recent call last):
ValidationError: Value for expiration not given or invalid.
>>> del battery.expiration
>>> battery.json()
'{"latest_charge": null}'

#

Field

字段的作用非常类似于装箱和拆箱

BooleanField

字段的作用非常类似于装箱和拆箱

IntegerField

字段的作用非常类似于装箱和拆箱

NumberField

字段的作用非常类似于装箱和拆箱

StringField

字段的作用非常类似于装箱和拆箱

DateField

字段的作用非常类似于装箱和拆箱

EnumField

字段的作用非常类似于装箱和拆箱

ListField

字段的作用非常类似于装箱和拆箱

MapField

字段的作用非常类似于装箱和拆箱

ComposableField

字段的作用非常类似于装箱和拆箱

Entity

ImmutableEntity

属性#

class Field(default=NULL, required=True, validation=None, in_dump=True, default_in_dump=True, nullable=False, immutable=False, aliases=())#

字段的作用非常类似于 c#/java 原语的装箱和拆箱。 __set__ 应该接受一个“primitive”或“raw”值,并为其创建一个“boxed”或“programmatically usable”值。 而 __get__ 应该返回 boxed 值,反过来 dump 应该将值拆箱为 primitive 或 raw 值。

参数:
  • types (primitive literaltypetypes 序列)

  • default (any, callable, 可选) -- 如果 default 是可调用的,则保证在 Entity 创建时返回有效值。

  • required (boolean, 可选)

  • validation (callable, 可选)

  • dump (boolean, 可选)

property name#
property required#
property type#
property default#
property in_dump#
property default_in_dump#
property nullable#
property is_nullable#
property immutable#
_order_helper = 0#
set_name(name)#
__get__(instance, instance_type)#
__set__(instance, val)#
__delete__(instance)#
box(instance, instance_type, val)#
unbox(instance, instance_type, val)#
dump(instance, instance_type, val)#
validate(instance, val)#
返回:

如果 val 有效

返回类型:

True

Raises:

ValidationError --

class BooleanField(default=NULL, required=True, validation=None, in_dump=True, default_in_dump=True, nullable=False, immutable=False, aliases=())#

基类: Field

字段的作用非常类似于 c#/java 原语的装箱和拆箱。 __set__ 应该接受一个“primitive”或“raw”值,并为其创建一个“boxed”或“programmatically usable”值。 而 __get__ 应该返回 boxed 值,反过来 dump 应该将值拆箱为 primitive 或 raw 值。

参数:
  • types (primitive literaltypetypes 序列)

  • default (any, callable, 可选) -- 如果 default 是可调用的,则保证在 Entity 创建时返回有效值。

  • required (boolean, 可选)

  • validation (callable, 可选)

  • dump (boolean, 可选)

_type#
box(instance, instance_type, val)#
BoolField#
class IntegerField(default=NULL, required=True, validation=None, in_dump=True, default_in_dump=True, nullable=False, immutable=False, aliases=())#

基类: Field

字段的作用非常类似于 c#/java 原语的装箱和拆箱。 __set__ 应该接受一个“primitive”或“raw”值,并为其创建一个“boxed”或“programmatically usable”值。 而 __get__ 应该返回 boxed 值,反过来 dump 应该将值拆箱为 primitive 或 raw 值。

参数:
  • types (primitive literaltypetypes 序列)

  • default (any, callable, 可选) -- 如果 default 是可调用的,则保证在 Entity 创建时返回有效值。

  • required (boolean, 可选)

  • validation (callable, 可选)

  • dump (boolean, 可选)

_type#
IntField#
class NumberField(default=NULL, required=True, validation=None, in_dump=True, default_in_dump=True, nullable=False, immutable=False, aliases=())#

基类: Field

字段的作用非常类似于 c#/java 原语的装箱和拆箱。 __set__ 应该接受一个“primitive”或“raw”值,并为其创建一个“boxed”或“programmatically usable”值。 而 __get__ 应该返回 boxed 值,反过来 dump 应该将值拆箱为 primitive 或 raw 值。

参数:
  • types (primitive literaltypetypes 序列)

  • default (any, callable, 可选) -- 如果 default 是可调用的,则保证在 Entity 创建时返回有效值。

  • required (boolean, 可选)

  • validation (callable, 可选)

  • dump (boolean, 可选)

_type = ()#
class StringField(default=NULL, required=True, validation=None, in_dump=True, default_in_dump=True, nullable=False, immutable=False, aliases=())#

基类: Field

字段的作用非常类似于 c#/java 原语的装箱和拆箱。 __set__ 应该接受一个“primitive”或“raw”值,并为其创建一个“boxed”或“programmatically usable”值。 而 __get__ 应该返回 boxed 值,反过来 dump 应该将值拆箱为 primitive 或 raw 值。

参数:
  • types (primitive literaltypetypes 序列)

  • default (any, callable, 可选) -- 如果 default 是可调用的,则保证在 Entity 创建时返回有效值。

  • required (boolean, 可选)

  • validation (callable, 可选)

  • dump (boolean, 可选)

_type#
box(instance, instance_type, val)#
class DateField(default=NULL, required=True, validation=None, in_dump=True, default_in_dump=True, nullable=False, immutable=False, aliases=())#

基类: Field

字段的作用非常类似于 c#/java 原语的装箱和拆箱。 __set__ 应该接受一个“primitive”或“raw”值,并为其创建一个“boxed”或“programmatically usable”值。 而 __get__ 应该返回 boxed 值,反过来 dump 应该将值拆箱为 primitive 或 raw 值。

参数:
  • types (primitive literaltypetypes 序列)

  • default (any, callable, 可选) -- 如果 default 是可调用的,则保证在 Entity 创建时返回有效值。

  • required (boolean, 可选)

  • validation (callable, 可选)

  • dump (boolean, 可选)

_type#
box(instance, instance_type, val)#
dump(instance, instance_type, val)#
class EnumField(enum_class, default=NULL, required=True, validation=None, in_dump=True, default_in_dump=True, nullable=False, immutable=False, aliases=())#

基类: Field

字段的作用非常类似于 c#/java 原语的装箱和拆箱。 __set__ 应该接受一个“primitive”或“raw”值,并为其创建一个“boxed”或“programmatically usable”值。 而 __get__ 应该返回 boxed 值,反过来 dump 应该将值拆箱为 primitive 或 raw 值。

参数:
  • types (primitive literaltypetypes 序列)

  • default (any, callable, 可选) -- 如果 default 是可调用的,则保证在 Entity 创建时返回有效值。

  • required (boolean, 可选)

  • validation (callable, 可选)

  • dump (boolean, 可选)

box(instance, instance_type, val)#
dump(instance, instance_type, val)#
class ListField(element_type, default=NULL, required=True, validation=None, in_dump=True, default_in_dump=True, nullable=False, immutable=False, aliases=())#

基类: Field

字段的作用非常类似于 c#/java 原语的装箱和拆箱。 __set__ 应该接受一个“primitive”或“raw”值,并为其创建一个“boxed”或“programmatically usable”值。 而 __get__ 应该返回 boxed 值,反过来 dump 应该将值拆箱为 primitive 或 raw 值。

参数:
  • types (primitive literaltypetypes 序列)

  • default (any, callable, 可选) -- 如果 default 是可调用的,则保证在 Entity 创建时返回有效值。

  • required (boolean, 可选)

  • validation (callable, 可选)

  • dump (boolean, 可选)

_type#
box(instance, instance_type, val)#
unbox(instance, instance_type, val)#
dump(instance, instance_type, val)#
validate(instance, val)#
返回:

如果 val 有效

返回类型:

True

Raises:

ValidationError --

class MapField(default=NULL, required=True, validation=None, in_dump=True, default_in_dump=True, nullable=False, immutable=True, aliases=())#

基类: Field

字段的作用非常类似于 c#/java 原语的装箱和拆箱。 __set__ 应该接受一个“primitive”或“raw”值,并为其创建一个“boxed”或“programmatically usable”值。 而 __get__ 应该返回 boxed 值,反过来 dump 应该将值拆箱为 primitive 或 raw 值。

参数:
  • types (primitive literaltypetypes 序列)

  • default (any, callable, 可选) -- 如果 default 是可调用的,则保证在 Entity 创建时返回有效值。

  • required (boolean, 可选)

  • validation (callable, 可选)

  • dump (boolean, 可选)

_type#
box(instance, instance_type, val)#
class ComposableField(field_class, default=NULL, required=True, validation=None, in_dump=True, default_in_dump=True, nullable=False, immutable=False, aliases=())#

基类: Field

字段的作用非常类似于 c#/java 原语的装箱和拆箱。 __set__ 应该接受一个“primitive”或“raw”值,并为其创建一个“boxed”或“programmatically usable”值。 而 __get__ 应该返回 boxed 值,反过来 dump 应该将值拆箱为 primitive 或 raw 值。

参数:
  • types (primitive literaltypetypes 序列)

  • default (any, callable, 可选) -- 如果 default 是可调用的,则保证在 Entity 创建时返回有效值。

  • required (boolean, 可选)

  • validation (callable, 可选)

  • dump (boolean, 可选)

box(instance, instance_type, val)#
dump(instance, instance_type, val)#
class Entity(**kwargs)#
property _initd#
__fields__#
_lazy_validate = False#
classmethod from_objects(*objects, **override_fields)#

Construct a new object of type cls from existing objects or dicts.

Allows the creation of new objects of concrete Entity subclasses by combining information from several sources. This can be any combination of objects and dictionaries passed in as positional arguments. When looking for the value of the fields of the Entity subclass, the first object that provides an attribute (or, in the case of a dict an entry) that has the name of the field or one of its aliases will take precedence. Any keyword arguments passed in will override this and take precedence.

参数:
  • cls (Entity subclass) -- The class to create, usually determined by call, e.g. PrefixRecord.from_objects(...).

  • *objects (tuple(object or dict)) -- Any combination of objects and dicts in order of decending precedence.

  • **override_fields (dict(str, object)) -- Any individual fields overriding possible contents from *objects.

classmethod from_json(json_str)#
classmethod load(data_dict)#
validate()#
__repr__()#

Return repr(self).

classmethod __register__()#
json(indent=None, separators=None, **kwargs)#
pretty_json(indent=2, separators=(',', ': '), **kwargs)#
dump()#
classmethod __dump_fields()#
__eq__(other)#

Return self==value.

__hash__()#

Return hash(self).

class ImmutableEntity(**kwargs)#

Bases: Entity

__setattr__(attribute, value)#

Implement setattr(self, name, value).

__delattr__(item)#

Implement delattr(self, name).