缘起
过去一直使用Java作为主编程语言,近期开始对Python感兴趣。很多时候,天然带上些Java的编程模式与思想。
Python在实现web请求时,request参数时常是通过dict对象,相当自由。
在使用Java时,我们常用POJO对象进行一组属性的传递,而在Python就很少见。
如何在Python实现类似Java的POJO对象?
- 有明确数量的属性
- 每个属性有明确的名称(区分大小写)
- 可序列化与反序列化
设计
按如上要求,我写了一个超类Simple
class Simple(object):
"""
POJO属性对象
.. 用法示例:
class Foo(Simple):
__slots__ = ('x', 'y', 'z')
def __init__(self, **kwargs):
super().__init__(**kwargs)
"""
__slots__ = ()
def __init__(self, **kwargs):
for k in kwargs.fromkeys(self.__slots__):
if k in kwargs:
setattr(self, k, kwargs[k])
@property
def json(self):
return {s: getattr(self, s) for s in self.__slots__ if hasattr(self, s)}
使用
场景假设,有一个request请求,使用json参数,参数要求4个,分别为
- app: str, 必须
- name: str, 必须
- ackType: int, 必须
- message: str, 可选
按如上要求,我们设计了一个类EventAck
class EventAck(Simple):
__slots__ = ('app', 'name', 'ackType', 'message')
def __init__(self, **kwargs):
super().__init__(**kwargs)
我们可以这样使用
...
params = EventAck(app='test', name='iamtestname')
if self._EVENT_TYPE_HEART == event_type:
params.ackType = 0
requests.post(url, json=params.json)
return
if self._EVENT_TYPE_MSG == event_type:
bookkeeping = Bookkeeping(**json.loads(data))
params.ackType = 1
params.message = bookkeeping.id
requests.post(url, json=params.json)
if not self.is_already_received(bookkeeping.id):
self.mark_received(bookkeeping.id)
if bookkeeping.action in self.listener_map:
for listener in self.listener_map[bookkeeping.action]:
listener.process(bookkeeping)
...
说明:
- 明确数量及名称的属性,通过
__slots__
限定,所有不在__slots__
内的属性都会抛出错误,我们可以认为__slots__
里定义的就是类java POJO对象的属性 - 序列化:通过超类Simple定义的json把Python对象序列化为dict
- 反序列化:通过
__init__(self, **kwargs)
从dict中反序列化成Python对象
精彩评论