【发布时间】:2016-11-08 18:55:16
【问题描述】:
我知道以前已经回答过类似的问题,但是在浏览网页数小时后,我仍然无法正确解决我的问题(或“python-way”解决方案)
我正在使用以下“数据库”模块将任何对象插入 MongoDB:
from pymongo import MongoClient
import json
def insert(obj, collection_name):
with MongoClient(27017, 'localhost') as client:
if hasattr(obj, '__dict__'):
doc = obj.__dict__
else:
doc = json.dumps(obj)
return client['test'][collection_name].insert_one(doc).inserted_id
def get_one(collection_name, query):
with MongoClient(27017, 'localhost') as client:
return client['test'][collection_name].find_one(query)
这部分效果很好,因为我可以处理任何模块中的任何类并以通用方式存储对象。
我面临的问题是从 MongoDB 重新加载一个对象并将其转换回正确的类。
我有一个通用类“操作”(代表可以对银行/货币帐户执行的操作:
import database
class Operation(object):
def __init__(self):
self._id = 'OPE-{}'.format(str(uuid.uuid1()))
@property
def id(self):
return self._id
def save(self):
database.update(self, 'operations')
def create_from_dict(d):
operation = Operation()
for key, value in d.items():
operation.__dict__[key] = value
return operation
def get(operation_id):
return create_from_dict(database.get_one('operations', {'_id': operation_id}))
直到此时一切正常,我可以实例化任何 Operation 对象,将其插入 MongoDB 并使用它的 id 将其加载回来。
现在我有两个从“操作”派生的新类“费用”和“信用”
import uuid
from operation import Operation
class Credit(Operation):
def __init__(self):
Operation.__init__(self)
self._id = 'CRE-{}'.format(uuid.uuid1())
@property
def id(self):
return self._id
和
import uuid
from operation import Operation
class Fee(Operation):
def __init__(self):
Operation.__init__(self)
self._id = 'FEE-{}'.format(uuid.uuid1())
@property
def id(self):
return self._id
我们的想法是保留在“操作”类中保存/加载对象的代码,并在需要时创建简单的派生类。 所以“Operation”类应该能够动态地将加载的对象从 Operation 转换为 Credit/Fee/Transfer...
我试图做的是在所有类上添加以下行以存储对象类型:
self.type = self.__class__
或者(因为类不能直接序列化为json)
self.type = self.__name__
但我不知道如何实现:
def create_from_dict(d):
operation = Operation()
for key, value in d.items():
operation.__dict__[key] = value
operation.__class__ = get_type_from_name(operation.type) #This is the function I'm trying to implement
return operation
在对对象进行编码以将其从另一个模块转换回时,我是否应该同时存储模块和类名?
很抱歉这个问题很长,但我想完整描述我的代码背后的逻辑 我对任何建议都非常开放!
编辑: locals() 或 globals() 可以走吗?您将类名传递给 get_type_from_name() 方法并返回相应的类? 高级 Python 专家的另一个问题:这是正确的方法吗?
【问题讨论】:
标签: python json mongodb dictionary casting