【问题标题】:Inheriting and modifying __init__() method继承和修改 __init__() 方法
【发布时间】:2014-03-13 19:40:02
【问题描述】:

我的实验室很快就会收到一些新设备,我正在编写自己的 modbus 脚本来自动化测试过程。到目前为止,这是我不得不用我有限的编程能力来应对的最复杂的任务。

我不想从头开始编写一个新类来管理命令,而是创建一个类EZTcomm,它从bytearray 继承其功能,并添加一个EZTcomm.crc 属性来存储循环冗余校验和。

在阅读了this question 和 docs.python.org 之后,我仍然对如何做到这一点感到困惑。似乎如果我想在我的新类中修改 __init__() 方法,那么我需要先显式调用 bytearray.__init__(),但我不知道如何将 EZTcomm 调用中的参数传递给 @ 987654329@,我也不知道如何使用bytearray.__init__()调用中的参数作为变量来计算CRC。

这是我迄今为止所写的:

class EZTcomm(bytearray):

    def __init__(self, *args, **kwargs):
        bytearray.__init__(self, *args, **kwargs)
        self.check = crc(args)

    def CRC(bytearray_in):
        '''Calculates a Cyclical Redundancy Checksum (CRC16).'''
        crc = 0xFFFF
        for work_byte in bytearray_in:
            crc ^= work_byte
            n = 0
            while n in range(8):
                if (crc & 0x0001):
                    crc >>= 1
                    crc ^= 0xA001
                else:
                    crc >>= 1
                n += 1
        return crc

############

test = EZTcomm([0x01,0x03,0x00,0x23,0x00,0x02])
print(test)
print(test.check)

这是否接近我想要的工作方式?我应该做些什么不同的事情?

【问题讨论】:

标签: python inheritance python-3.x modbus crc16


【解决方案1】:

你已经接近了。您希望 CRC 成为常规函数1

def CRC(bytearray_in):
    '''Calculates a Cyclical Redundancy Checksum (CRC16).'''
    crc = 0xFFFF
    for work_byte in bytearray_in:
        crc ^= work_byte
        n = 0
        while n in range(8):
            if (crc & 0x0001):
                crc >>= 1
                crc ^= 0xA001
            else:
                crc >>= 1
            n += 1
    return crc

您从子类的 init 中调用:

class EZTcomm(bytearray):

    def __init__(self, *args, **kwargs):
        bytearray.__init__(self, *args, **kwargs)
        self.check = CRC(self)

__init__ 中,self 是您正在创建的子类的实例。它是一个字节数组,所以它应该与 CRC 一起工作,假设 CRC 完全有效。当然这里可以复杂一点,用super来调用基类的__init__方法:

class EZTcomm(bytearray):

    def __init__(self, *args, **kwargs):
        super(EZTcomm, self).__init__(*args, **kwargs)
        # super().__init__(*args, **kwargs)  # python3.x only.
        self.check = CRC(self)

super 的优点是它可以让多重继承很好地工作,但总的来说,我建议人们在开始搞乱它之前真正知道他们在做什么。您应该遵循许多最佳实践以充分利用它。有关详细信息,请参阅:http://rhettinger.wordpress.com/2011/05/26/super-considered-super/

1你的 while 循环最好是 for 循环:for n in range(8):...
如果你这样做,你删除 n = 0n += 1 行.

【讨论】:

  • while 更改为 for 并删除 n += 1
  • 另外,这是一个低效的 CRC 实现。您可以通过预先计算一个包含 256 个条目的表来避免内部循环。
  • @pat -- 我敢肯定......你对应该对 OP 代码进行的更改是正确的。我将保持原样以使其从上方立即可识别,但希望 OP 会注意到您的 cmets 并进行适当的更改。我不知道 CRC 是什么,所以我相信你的话,这个实现是有效的(至少)。
  • @mgilson -- 谢谢,这似乎完成了我想做的事情。一旦我获得更多经验,您提供的链接看起来会非常有用。
  • @pat -- 很高兴知道,但我现在不关心效率,只是我可以理解它是如何工作的。直到几天前,我什至不知道 modbus 是什么或如何计算 CRC。您是否推荐任何有关 CRC 的入门级读物?
猜你喜欢
  • 1970-01-01
  • 2011-08-03
  • 1970-01-01
  • 2013-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-31
相关资源
最近更新 更多