修改功能并保持代码的可操作性
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了修改功能并保持代码的可操作性相关的知识,希望对你有一定的参考价值。
我不是一个专业的程序员,但我会不时地使用Python来满足我的科学需求。所以我想了解最常用的Pythonic方法:
我正在使用已经存在的模块,有些类看起来像那样
class ATS(Instrument):
def __init__(self, ..., dll_path: str):
...
self._dll = ctypes.cdll.LoadLibrary(dll_path)
...
def _call_dll(self, func_name: str, *args) -> None:
func = getattr(self._dll, func_name)
output = func(*args)
...
我发现我需要使用不同的DLL来调用它自己的函数(不幸的是,不同DLL中函数的名称可以是相同的)。
问题是:修改_call_dll
函数的最Pythonic方法是什么,以明确指定我想用来调用特定函数的DLL。同时,我希望保持其余代码的可操作性,使用旧版本的_call_dll
。
我看到有几种方法可以做到这一点,但我不确定哪一种最专业,更好的造型。
- 为我想要使用的每个
_call_dll_n
创建自己的dll_n
函数,但它不紧凑而且不错。 - 在函数名称中添加一些前缀以指定DLL,如
class ATS(Instrument): def __init__(self, ..., dll_path, dll_path_1, ...): ... self._dll = ctypes.cdll.LoadLibrary(dll_path) self._dll_1 = ctypes.cdll.LoadLibrary(dll_path_1) ... def _call_dll(self, pre_func_name: str, *args) -> None: if prefix_func_name[:5] == 'dll_1': dll = self._dll_1 func_name = pre_func_name[5:] func = getattr(dll, func_name) ... else: dll = self._dll # Default DLL. func_name = pre_func_name
- 制作my_call_dll:
def _my_call_dll(self, func_name: str, dll = None, *args)) if dll is None: self._call_dll(self, func_name, *args) else: dll_bckp = self._dll self._dll = dll self._call_dll(self, func_name, *args) self._dll = dll_bckp
您对这个特定示例的帮助表示赞赏,但是关于如何工作和修改已有的函数/类的更一般的想法也非常受欢迎。
您无需修改代码;正如您所介绍的那样,ATS课程已经允许您所描述的内容。相反:创建多个ATS实例,每个实例指定要使用的DLL。
您对问题的描述需要两部分:
- 一个mapping,从一些键到DLL文件路径。
- 一个API wrapper,允许您在调用API时指定上述映射的键。
在Python中,built-in ‘dict’ type是实现映射的自然方式。您可以使用普通字符串作为键。
import os.path
# You might get the path to your DLL files some other way,
# for example by reading a process environment variable.
# In this example I just hard-code the path root.
dll_file_path_root = os.path.join('/usr/lib', 'ats')
dll_file_paths = {
'foo': os.path.join(dll_file_path_root, 'foo.dll'),
'bar': os.path.join(dll_file_path_root, 'bar_v5.dll'),
'baz': os.path.join(dll_file_path_root, 'super_baz.dll'),
}
正如您在上面提到的那样,现有的ATS类已经实现了一个API包装器。每个实例都将保存一个引用(其内部使用的_dll
属性),ATS实例将与之对话的DLL。该类将使用您指定的任何DLL初始化ATS的每个实例。所以:
# Create an ATS instance that holds a reference to the ‘foo.dll’ library.
foo_ats = ATS(dll_path=dll_file_paths['foo'])
# Create an ATS instance that holds a reference to the ‘bar_v5.dll’ library.
bar_ats = ATS(dll_path=dll_file_paths['bar'])
# Call the ‘lorem’ function in the ‘foo.dll’ library.
foo_ats._call_dll(func_name='lorem')
# Call the ‘lorem’ function in the ‘bar_v5.dll’ library.
bar_ats._call_dll(func_name='lorem')
这是定义类的主要好处之一:它们封装了一类对象的常见行为,同时允许每个对象具有区分它们的各个属性。
以上是关于修改功能并保持代码的可操作性的主要内容,如果未能解决你的问题,请参考以下文章
创建一个叫做机动车的类: 属性:车牌号(String),车速(int),载重量(double) 功能:加速(车速自增)减速(车速自减)修改车牌号,查询车的载重量。 编写两个构造方法:一个没有(代码片段
11.按要求编写Java应用程序。 创建一个叫做机动车的类: 属性:车牌号(String),车速(int),载重量(double) 功能:加速(车速自增)减速(车速自减)修改车牌号,查询车的(代码片段