我正在编写一个模块,用于从本地SQLite数据库访问某些数据,并希望最终用户功能能够像这样工作:
import pyMyDB
myDBobj = pyMyDB.MyDB( '/path/to/DB/file' ) # Instance of the class MyDB
用户只需创建一个连接数据库的对象
然后,根据需要,我希望用户可以访问不同的子模块来处理来自数据库的数据。例如,Driving
提供某些功能,Walking
提供其他功能,我喜欢这样访问:
result = myDBobj.Driving.GetTachometerReading()
或
result = myDBobj.Walking.GetShoeType()
我的问题关于如何制作子模块Driving
& Walking
可以访问父 Object (不仅仅是Parent模块的类/函数,而是实例化的对象)。
如果我让我的文件heirarchy像这样:
pyMyDB/
__init__.py # imports the below modules as so:
MyDB_class.py # imported as *, contains MyDB class definition
Driving.py # imported normally via `import Driving`
Walking.py # imported normally
其中__init__.py
导入MyDB_class.py
(包含数据库类)并导入Driving/Walking.py
,然后
用户可以执行pyMyDB.Driving.some_func()
,但some_func()
实际上无法访问实例化的MyDB
对象,对吗?
有没有人遇到让子模块访问实例化对象的方法?
这是我目前的解决方案。这似乎太复杂了。
首先,我必须使用额外的globals.py
文件来克服循环模块导入(Like this hint)。
在Driving
模块中,我创建了一个名为Drv
的新类,它用于复制MyDBobj
,但也有我想要的额外方法,例如{ {1}}。
Driving.py:
Driving.GetTachometerReading()
然后,为了完成子索引(class DrvClass( MyDB ):
def __init__(self, MyDBobj):
self.attribute1 = MyDBobj.attr1
self.attribute2 = MyDBobj.attr2
.... # copy all attribute values!
def GetTachometerReading(self):
.... #some function here
),在MyDBobj.Driving.GetTach()
模块中,我通过
Driving()
类>
MyDB
现在,用户可以执行:def temp_driving(self):
return DrvClass( self ) # pass the MyDBobj
MyDB.Driving = temp_driving # add the above method to the MyDB class
,其中MyDBobj.Driving().GetTachometerReading()
返回具有新MyDBobj.Driving()
功能的新DrvClass
对象。我不喜欢我必须将GetTachometer()
称为函数。
您如何看待 - 有更好/更简单的方法吗?
之所以我希望MyDB类是分开的,是因为我们的访问方法可能会改变,而不会改变分析功能(驾驶/步行),反之亦然。因此,我不想直接将MyDB访问技术添加到单独的Driving& amp;步行模块。
提前感谢您的圣人建议!
答案 0 :(得分:0)
我想我可能会在客户端使用不同的访问方法。如果客户端使用这样的协议:
result = myDBobj.Driving_GetTachometerReading()
然后可以直接将此名称添加到子模块Driving.py中的类中:
import pyMyDB
def GetTachometerReading(self):
# self will be the MyDB instance
pyMyDB.MyDB.Driving_GetTachometerReading = GetTachometerReading
但是,如果你按照你的方法进行设置,那么我认为它可以得到改进。实际上,你为每次调用Driving函数创建了一个新的Driving实例,但这并不好。但是,我们需要在实例化MyDB本身时创建一个实例。然而,这似乎很棘手,因为当时我们似乎并不知道要包含哪些子模块。我通过让每个子模块将其方法列表注入MyDB来解决这个问题。像这样:
pyMyDB:
import functools
class MyDB(object):
submodule_methods = {}
def __init__(self):
for k,v in self.submodule_methods.items():
self.__dict__[k] = SubmodulePointer(self,v)
self.db_stuff = "test"
class SubmodulePointer(object):
def __init__(self,db,methods):
self.db = db
for name,func in methods.items():
self.__dict__[name] = functools.partial(func,db)
然后对于每个子模块,例如驾驶我们做:
import pyMyDB
def GetTachometerReading(self):
# self here is the db instance, as if this was a method on the db
print(self.db_stuff)
pyMyDB.MyDB.submodule_methods["Driving"] = {"GetTachometerReading":GetTachometerReading}
然后客户可以这样做:
import pyMyDB
import Driving
m = pyMyDB.MyDB()
m.Driving.GetTachometerReading()
如你所愿。一种更简单的方法,稍微更传统的风格就是让驾驶成为一个属于自己的类:
pyMyDB:
import functools
class MyDB(object):
submodule_classes = []
def __init__(self):
for c in self.submodule_classes:
self.__dict__[c.__name__] = c(self)
self.db_stuff = "test"
然后对于每个子模块,例如驾驶我们做:
import pyMyDB
class Driving(object):
def __init__(self,db):
self.db = db
def GetTachometerReading(self):
# self here is the Driving instance,
# but we have access to the db
print(self.db.db_stuff)
pyMyDB.MyDB.submodule_classes.append(Driving)
这意味着Driving类中的方法看起来不像MyDB上的方法,但这可能是一个优势。我不确定这是否是你想要的。