Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/351.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 创建基于类的可重用应用程序_Python_Multiple Inheritance_Mixins_Python 2.x_Code Reuse - Fatal编程技术网

Python 创建基于类的可重用应用程序

Python 创建基于类的可重用应用程序,python,multiple-inheritance,mixins,python-2.x,code-reuse,Python,Multiple Inheritance,Mixins,Python 2.x,Code Reuse,我试图在Python2.6中创建一个可重用的应用程序 我正在开发用于监听GPS跟踪设备的服务器端脚本。脚本正在使用套接字 我有一个基类,它定义了处理设备发送的数据的基本方法 类MyDevice(对象): def_uuuinit_uuu(self,db) self.db=db#这个类定义了连接/使用数据库的方法 def初始化_db(自身): ... def句柄_数据(自身): self.initialize_db() ... self.process_data() def过程_数据(自身): ..

我试图在Python2.6中创建一个可重用的应用程序

我正在开发用于监听GPS跟踪设备的服务器端脚本。脚本正在使用套接字

我有一个基类,它定义了处理设备发送的数据的基本方法

类MyDevice(对象):
def_uuuinit_uuu(self,db)
self.db=db#这个类定义了连接/使用数据库的方法
def初始化_db(自身):
...
def句柄_数据(自身):
self.initialize_db()
...
self.process_data()
def过程_数据(自身):
...
self.categorize_data()
def分类_数据(自身):
...
self.save_data()
def保存_数据(自身):
...
这个基类适用于许多设备,因为这些设备之间只有一些细微的差别。因此,我为每个特定的设备类型创建了一个类,并对该设备进行了特定的安排

类MyDeviceType1(Mydevice):
定义初始化(自我,数据库):
超级(MyDeviceType1,self)。\uu初始化(db)
def分类_数据(自身):
超级(MyDeviceType1,self)。对数据进行分类(self)
self.prepopulate_data()
...  # 执行特定于设备的其他操作
def预填充_数据(自身):
“”“这是特定于类型1设备的”“”
...
类别MyDeviceType2(Mydevice):
定义初始化(自我,数据库):
超级(MyDeviceType1,self)。\uu初始化(db)
def分类_数据(自身):
超级(MyDeviceType1,self)。对数据进行分类(self)
self.unpopulate_数据()
...  # 执行特定于设备的其他操作
def未填充_数据(自身):
“”“这是特定于类型2设备的”“”
...
我有监听特定套接字的套接字侦听器,并调用相关类(
MyDeviceType1
MyDeviceType2
),如:

conn,address=socket.accept()
...
线程。启动新线程(MyDeviceType1(db连接器)。处理数据,())
这种结构对我来说很好,也很有用。一个设备(MyDevice)可能有许多继承基类的子类型(MyDeviceType1、MyDeviceType2)

并且有不止一种类型的基本设备。因此,还有其他设备具有子类型OtherDeviceType1等

MyDevice
OtherDevice
的工作原理完全不同,因此它们是基本类型,并且它们的底层代码都非常不同

我还有一些附加功能。几乎所有设备基本类型的一个或两个子类型都可以使用这些功能

所以我想准备一个可重用(可插入)的类,它可以被任何需要这些功能的子类型继承

类MyAddOn(对象):
def删除不可用的数据(自身):
...
def分类_数据(自身):
超级的???
self.remove_无法使用的_数据()
这是我卡住的部分。由于这是一个独立的模块,因此不应从
MyDevice
OtherDevice
等继承,但并非所有子设备类型都使用这些功能,我也不能从
MyAddOn
继承
MyDevice

只有逻辑方法看起来像是从
MyDevice
MyAddOn
继承子类型
MyDeviceSubType1

类MyDeviceType1(Mydevice,MyAddOn):
定义初始化(自我,数据库):
超级(MyDeviceType1,self)。\uu初始化(db)
def分类_数据(自身):

>>super(MyDeviceType1,self)。对数据进行分类(self)这在python中称为协作多重继承,工作正常

您称之为“Addon”类的东西通常称为“Mixin”

只需在Mixin类中调用
super
方法:

class MyAddOn(object):
    def remove_unusable_data(self):
       ...

    def categorize_data(self):
        super(MyAddon,self).categorize_data()
        self.remove_unusable_data()
我想指出一些事情:

  • 方法解析顺序为从左到右
  • 你必须打超级电话
  • 您应该使用**kwargs进行协作继承

在这里调用
super
似乎是违反直觉的,因为
MyAddon
的父级没有名为
categorize\u data
的属性,您可能会认为这种表示法会失败

这就是
super
功能发挥作用的地方。认为这种行为对Python来说是最好的。 <>与C++或java不同,超函数不一定调用类的父类。事实上,不可能预先知道
super
将调用哪个函数,因为它将在运行时根据

python中的
super
实际上应该被调用
next
,因为它将调用继承树中的下一个方法

对于mixin,调用super尤其重要,即使您是从
对象继承的

有关更多信息,我建议观看Raymond Hettinger在pycon 2015上的精彩演讲


这是一种在python中使用的优秀模式。以下是我在编写遵循以下规则的结构化应用程序时经常遇到的一种模式:

我有一个用于生产的库类:

class BaseClassA(object):
   def __init__(self, **kwargs):
       ... Do something that's important for many modules
   def ...   

class BaseClassB(object):
   def __init__(self, **kwargs):
       ... Do something that's important for many modules
   def ...   
现在您得到一个特性请求,在特定情况下,
BaseClassA
BaseClassB
都应该实现特性X

根据open-close,您不必触摸现有代码来实现该功能,根据DRY,您不应重复代码

解决方案是创建
FeatureMixin
并创建从基类和mixin继承的空子类:

class FeatureMixin(object):
    def __init__(self,**kwargs):
        ...do something specific
        return super(FeatureMixin,self).__init__(**kwargs)
class ExtendedA(FeatureMixin,BaseClassA):
   pass
class ExtendedB(FeatureMixin,BaseClassB):
   pass

为什么添加的功能必须是“可插入的”?看起来你的插件操作的是一些可以由设备获取的数据,更像是一个进行转换的实用功能。如果这不需要设备的任何状态,为什么还要麻烦将此实用程序功能强制到设备上?从设备获取数据并将其传递给实用程序funct