我知道以前已经回答过类似的问题,但在花了几个小时浏览网页后,我仍然无法找到解决我的问题的正确解决方案(或“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}))
直到此时一切正常,我可以实例化任何操作对象,将其插入 MongoDB 并使用它的 id 将其加载回来。
现在我有两个从“Operation”派生的新类“Fee”和“Credit”
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”类应该能够将加载的对象从“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 专家来说,还有一个问题:这是正确的方法吗?
最佳答案
使用您建议的 self.type = self.__name__
想法,您可以尝试对 get_type_from_name
函数进行此实现:
def get_type_from_name(name):
name_to_type = {'Credit': Credit, 'Fee':Fee}
return name_to_type[name]
不过,我不太确定我是否完全理解您的问题,所以如果这不是您想要的,请告诉我。
关于python - 在python中动态将dict转换为类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40494438/