如下图所示,在Spyder开发环境内建立了modbus2.py程序,在modbus2.py中定义了MainWindow类,并在类内用def定义了modbus_crc_hex(hex_str: str) -> str:检验码自动计算程序。同时,在类内直接调用modbus_crc_hex(hex_str: str) -> str:函数。点击“运行”后,提示TypeError: modbus_crc_hex() takes 1 positional argument but 2 were given。该错误的意思的modbus_crc_hex()函数定义了一个参数,但是调用的时候传递了两个参数,所以提示错误。

大家可以复制第二个图中的代码运行亲自体验一下。发生这个错误的原因是:在class类内定义并调用函数的时候,默认传递隐形self参数和modbus_crc_hex函数中定义的显性参数hex。

如何修正这种错误呢。下面介绍两种方法,伙伴们继续往下看。

class MainWindow:  #将ui文件写到括号里面
    def __init__(self):
        datas="3B 03 00 01 00 05"
        crc_bytes = self.modbus_crc_hex(datas)   #计算CRC校验位
        print(crc_bytes)
    
    
#定义一个小端模式的crc校验程序    
    def modbus_crc_hex(hex_str: str) -> str:
        # 移除空格并验证输入
        hex_str = hex_str.replace(" ", "").upper()
        if not all(c in "0123456789ABCDEF" for c in hex_str):
            raise ValueError("输入包含非十六进制字符")
        if len(hex_str) % 2 != 0:
            raise ValueError("输入长度必须是偶数(每个字节两个字符)")
        
        # 将十六进制字符串转换为字节序列
        data = bytes.fromhex(hex_str)
        
        # 计算CRC16值
        crc = 0xFFFF
        polynomial = 0xA001  # Modbus CRC16多项式
        
        for byte in data:
            crc ^= byte
            for _ in range(8):
                if crc & 0x0001:
                    crc = (crc >> 1) ^ polynomial
                else:
                    crc >>= 1
        
        # 转换为小端序十六进制字符串
        crc_low = crc & 0xFF
        crc_high = (crc >> 8) & 0xFF
        return f"{crc_low:02X}{crc_high:02X}"

if __name__ == "__main__":
    mainWindow = MainWindow()        #MainWindow对应class MainWindow的名称

修正方法1:在上图的modbus_crc_hex(hex_str: str) -> str:函数定义中添加self参数,即modbus_crc_hex(self,hex_str: str) -> str:。点击“运行”运行后,自动计算出CRC校验码D153。运行正常。

修正方法2:如下图所示,将modbus_crc_hex(self,hex_str: str) -> str:函数从类class里面调整出来,定义为模块函数。定义和在类class调用模块函数的时候注意两点。第一点是去掉modbus_crc_hex函数里面的self,即变为modbus_crc_hex(hex_str: str) -> str:。第二点是在class类内调用modbus_crc_hex的时候去掉函数前的self.。因为是直接调用模块函数,不在需要类对象self参数。点击“运行”后,也能自动计算出CRC校验码D153。

以上就是解决TypeError: crc() takes 1 positional argument but 2 were given错误的方法。归根结底是大家弄清楚class类和def函数定义的区别与调用规则。想必通过本文后大家应该很清楚了。

小伙伴们请多多点赞、关注、收藏吧!大家的鼓励是我撰写更多实用技术原创文章的动力源泉。感谢大家啦!

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐