Python中的类层次结构

Python中的类层次结构,python,class-hierarchy,Python,Class Hierarchy,我有一个relaisboard,它使用Python绑定通过firmata协议连接到arduino。使用pyfirmata进行通信时不会出现问题 relaisboard有16个relais。每组3个继电器为一个通道。每个通道都连接到被测输入或输出设备。这仅仅是为了对发布的目的有一个粗略的描述 下面是代码的框架 #!/usr/bin/env python __version__ = '0.1' # Fault Injection Unit # Power is connected to Fau

我有一个relaisboard,它使用Python绑定通过firmata协议连接到arduino。使用pyfirmata进行通信时不会出现问题

relaisboard有16个relais。每组3个继电器为一个通道。每个通道都连接到被测输入或输出设备。这仅仅是为了对发布的目的有一个粗略的描述

下面是代码的框架

#!/usr/bin/env python

__version__ = '0.1'

# Fault Injection Unit

# Power is connected to Fault Bus 1
# Ground is connected to Fault Bus 2

from pyfirmata import Arduino

class FaultInsertionBoard(object):

    def __init__ (self, comPort = 'COM3'):
        """Initalize the Fault insertion Board

        Open communication with host via serial port

        Arguments:
        comPort -- The serial port used to connect the board to the host.
        """
        self.board = Arduino(comPort)

    class Channel(object):

        def __init__ (self, aChannel):
            """ Create a Channel"""
            pass

        def NoFault():
            """ Set the channel to the "No fault" condition

            No Fault condition is:
            -- DUT channel connected to the testing sistem
            -- DUT channel disconnected from the Fault bus 1  
            -- DUT channel disconnected from the Fault bus 2
            """
            pass


        def OpenCircuit():
            """ Set the channel to the "Open Circuit fault" condition

            Open Circuit fault condition is:
            -- DUT channel disconnected from the testing sistem
            -- DUT channel disconnected from the Fault bus 1  
            -- DUT channel disconnected from the Fault bus 2
            """
            pass

        def ShortToGround():
            """ Set the channel to the "Short to Ground fault" condition

            Open Circuit fault condition is:
            -- DUT channel disconnected from the testing sistem
            -- DUT channel disconnected from the Fault bus 1  
            -- DUT channel connected to the Fault bus 2
            """
            pass

        def ShortToPower():
            """ Set the channel to the "Short to Ground fault" condition

            Open Circuit fault condition is:
            -- DUT channel disconnected from the testing sistem: channel relay is open
            -- DUT channel connected to the Fault bus 1: Fault Bus 1 relay is closed 
            -- DUT channel disconnected from the Fault bus 2: Fault Bus 1 relay is open
            """
            pass

def main():

    FaultBoard = FaultInsertionBoard('COM3')
    VoutSensor = FaultBoard.Channel(0)  
    IOutSensor = FaultBoard.Channel(1)    
    VoutSensor.NoFault()
    IOutSensor.NoFault()
    VoutSensor.ShortToGround()
    IOutSensor.ShortToPower()

if __name__ == "__main__":
    main()
其中:

FaultInsertionBoard是中Arduino类的简单包装器 苍穹。 Channeln标识三个relai的第n组 无故障、短路电源、短路接地是 每个通道的三个relais实际值并不重要 配置 现在的问题是:我对用C编写的嵌入式固件有很好的经验,更不用说用Python了。显然,上面的代码是不正确的

有人能给我推荐一个类框架来实现上述功能吗?换句话说,我如何编写Python代码以驱动上述relais

PS:或者我可以这样写:

FaultBoard = FaultInsertionBoard('COM3')
FaultBoard.Channel(0).NoFault()
def main():
    fault_board = FaultInsertionBoard('COM3')
    v_out_sensor = fault_board.channels[0]  
    i_out_sensor = fault_board.channel[1]
    v_out_sensor.no_fault()
    v_out_sensor.short_to_ground()
    i_out_sensor.no_fault()
    i_out_sensor.short_to_ground()
def main():
    fault_board = FaultInsertionBoard('COM3')
    v_out_sensor = fault_board.channel(0)  
    i_out_sensor = fault_board.channel(1)
    v_out_sensor.no_fault()
    v_out_sensor.short_to_ground()
    i_out_sensor.no_fault()
    i_out_sensor.short_to_ground()
def main():
    fault_board = FaultInsertionBoard('COM3')
    for channel in fault_board.channels:
        channel.reset()

但我认为它不够优雅和清晰。

一方面,你的实际问题相当笼统,今后你应该尝试更具体一些。另一方面,初学者通常很难知道从哪里开始,因此我将为您提供一些设计技巧,帮助您克服这一挑战

没有嵌套类

嵌套类在Python中非常无用。完全合法,但毫无意义。它们不会为您提供对包含类的神奇访问,也不会像在Java中那样出现在任何实例中。嵌套所做的只是使名称空间更加复杂

我要做的第一件事是将通道移出板上。一个简单的不知情者就足够了。我将向您展示如何进一步使用它

命名约定

另一件需要记住的事情是Python命名约定。虽然这不是一项要求,但通常只将类名大写,而其他所有名称都是小写的,单词之间带有下划线,而不是大小写

在函数参数的默认值定义中,通常不在=周围加空格

在整个回答过程中,我将遵循这些惯例

继承与遏制

对于FaultInsertionBoard,您可能应该使用继承而不是包含:

这将使FaultInsertionBoard拥有Arduino的所有方法和属性。现在可以执行fault_board.method而不是fault_board.board.method,其中方法是Arduino类的某个方法

您可能需要定义一些额外的初始化步骤,如设置com_端口的默认值,以及稍后设置通道。您可以定义自己的_init__版本,并随时调用父类的实现:

class FaultInsertionBoard(Arduino):
    def __init__(self, com_port='COM3'):
        super().__init__(com_port)
如果您使用Python2.x,请使用superFaultInsertionBoard、self.\uuu init\uuu

添加频道

为了能够实际访问通道实例,您需要定义一些数据结构来保存它们,并预先初始化一些通道。数据结构可以作为属性直接访问,也可以通过对参数进行额外检查的方法访问

正如我前面提到的,嵌套Channel类根本不会向这个方向移动。事实上,由于您的Channel类可能需要访问其父板,我们将向其构造函数添加一个新的初始化参数:

class Channel:
    def __init__(self, channel_id, parent):
        self.id = channel_id
        self.parent = parent
你有几个选择。最简单的方法是在FaultInsertionBoard中初始化一系列通道,您可以通过[]访问这些通道,而不是:

现在,main将如下所示:

FaultBoard = FaultInsertionBoard('COM3')
FaultBoard.Channel(0).NoFault()
def main():
    fault_board = FaultInsertionBoard('COM3')
    v_out_sensor = fault_board.channels[0]  
    i_out_sensor = fault_board.channel[1]
    v_out_sensor.no_fault()
    v_out_sensor.short_to_ground()
    i_out_sensor.no_fault()
    i_out_sensor.short_to_ground()
def main():
    fault_board = FaultInsertionBoard('COM3')
    v_out_sensor = fault_board.channel(0)  
    i_out_sensor = fault_board.channel(1)
    v_out_sensor.no_fault()
    v_out_sensor.short_to_ground()
    i_out_sensor.no_fault()
    i_out_sensor.short_to_ground()
def main():
    fault_board = FaultInsertionBoard('COM3')
    for channel in fault_board.channels:
        channel.reset()
如果您确实希望使用括号访问通道,如通道0等,可以在FaultInsertionBoard中定义一个方法。保持_init__方法相同,可以添加另一个方法:

def channel(self, index):
    # Check index if you want to, possibly raise an error if invalid
    return self.channels[index]
在这种情况下,main将如下所示:

FaultBoard = FaultInsertionBoard('COM3')
FaultBoard.Channel(0).NoFault()
def main():
    fault_board = FaultInsertionBoard('COM3')
    v_out_sensor = fault_board.channels[0]  
    i_out_sensor = fault_board.channel[1]
    v_out_sensor.no_fault()
    v_out_sensor.short_to_ground()
    i_out_sensor.no_fault()
    i_out_sensor.short_to_ground()
def main():
    fault_board = FaultInsertionBoard('COM3')
    v_out_sensor = fault_board.channel(0)  
    i_out_sensor = fault_board.channel(1)
    v_out_sensor.no_fault()
    v_out_sensor.short_to_ground()
    i_out_sensor.no_fault()
    i_out_sensor.short_to_ground()
def main():
    fault_board = FaultInsertionBoard('COM3')
    for channel in fault_board.channels:
        channel.reset()
第一种方法的优点是允许您直接访问通道对象序列。由于对通道应用相同的操作,因此可以迭代所有通道,以获得更简单的界面:

def main():
    fault_board = FaultInsertionBoard('COM3')
    for channel in fault_board.channels:
        channel.no_fault()
        channel.short_to_ground()
便利方法

您似乎使用了操作x.no_故障;x、 在代码中多次对地短路。在这种情况下,创建所谓的便利方法通常是有帮助的。您可以将以下内容添加到频道:

然后main可能会这样:

FaultBoard = FaultInsertionBoard('COM3')
FaultBoard.Channel(0).NoFault()
def main():
    fault_board = FaultInsertionBoard('COM3')
    v_out_sensor = fault_board.channels[0]  
    i_out_sensor = fault_board.channel[1]
    v_out_sensor.no_fault()
    v_out_sensor.short_to_ground()
    i_out_sensor.no_fault()
    i_out_sensor.short_to_ground()
def main():
    fault_board = FaultInsertionBoard('COM3')
    v_out_sensor = fault_board.channel(0)  
    i_out_sensor = fault_board.channel(1)
    v_out_sensor.no_fault()
    v_out_sensor.short_to_ground()
    i_out_sensor.no_fault()
    i_out_sensor.short_to_ground()
def main():
    fault_board = FaultInsertionBoard('COM3')
    for channel in fault_board.channels:
        channel.reset()

您不显示FaultInsertInboard的代码;你希望如何得到帮助?你发布的代码不起作用还是什么?对不起,是我的错。我以为我把代码放进去了。请参阅我上面编辑的问题。不要定义嵌套类。它在Python中没有任何用途。如果这仅仅是一个缩进错误,请修复它。那么您要求我们为您实现您的类?