这是编写适用于不同构建的 MicroPython 模块的正确方法吗?

Is this the correct way to write a MicroPython module that works across different builds?

我正在为 I2C 温度传感器 (TMP117) 编写一个模块,优先考虑交叉兼容性。

BBC Micro:bit 和 Raspberry Pi Pico 上的 MicroPython 实现不同 - 一个重要的区别是 I2C 驱动程序的实现方式:

这个简单的命名差异确实会影响兼容性!

到目前为止,我已经找到了一个可行的解决方案,因此我的模块 tmp117.py 可以在两个平台上使用。 在 tmp117.py 中,当传感器 class 初始化时,它会检查 sysname 并声明函数指针 self.i2cWriteself.i2cRead,它们被分配了适合硬件的定义。

但是,我对 Python 还很陌生,我想我可能犯下了很多暴行,例如。命名空间处理不当或使用不适当的导入占用内存。有人可以评论这种方法是否合适吗?在可伸缩性、不必要的导入、名称空间等方面

main.py

# TMP117 minimal example code
from tmp117 import *
from time import sleep

mySensor = tmp117()

while True:
    # Read and print the temperature in various units
    tempC = mySensor.readTempC() # Celsius
    
    tempStringC = str(tempC) # convert temperature number to string
  
    print("it's " + tempStringC)
    
    sleep(1)

tmp117.py

# A simple class to read temperature from the TMP117 i2c temperature sensor
# Currently only supports reading temperature in C, F, K. Does not support
# alarms.

# This module has been tested with the following development boards:
#    • BBC Micro:bit
#    • Raspberry Pi Pico (RP2040)

import os


if os.uname().sysname == 'microbit':
    from microbit import *
else: # for Raspberry Pi Pico
    from machine import I2C
    i2c = I2C(0)
    
print("Running on " + os.uname().sysname)
    
# Register definitions
REG_TEMPC = b'\x00'

class tmp117(object):    
    def __init__(self, addr_=0x48, i2c_=i2c):
        if os.uname().sysname == 'microbit':
            self.i2c = i2c_
            self.addr = addr_
            self.i2cWrite = self.i2c.write
            self.i2cRead = self.i2c.read
        else:
            self.i2c = i2c_
            self.addr = addr_
            self.i2cWrite = self.i2c.writeto
            self.i2cRead = self.i2c.readfrom
    
    def readTempC(self):
        self.i2cWrite(self.addr, REG_TEMPC)
        data = self.i2cRead(self.addr, 2) # returns a bytes object
        tempDataRaw = int.from_bytes(data, 'big')
        # handle negatives (MicroPython int.from_bytes does not support signed conversion (yet)
        if tempDataRaw >= 0x8000:
            return -256.0 + (tempDataRaw - 0x8000) * 7.8125e-3 # One LSB equals 7.812 mdegC
        else:
            return tempDataRaw * 7.8125e-3 # One LSB equals 7.812 mdegC

我选择做同样的事情是定义 _PLATFORM 变量,相应地设置它并在以后使用它:

import os

if os.uname().sysname == 'microbit':
    _PLATFORM = 'microbit'
elif os.uname().sysname == 'rpico':  # not sure about real value
    _PLATFORM = 'pico'
else:
    raise Exception('Unsupported platform')


if _PLATFORM == 'microbit':
    from microbit import *
elif _PLATFORM == 'pico': # for Raspberry Pi Pico
    from machine import I2C
    i2c = I2C(0)


print("Running on {}".format(_PLATFORM))    # <<--- use format() function to save RAM
    
# Register definitions
REG_TEMPC = b'\x00'

class tmp117(object):    
    def __init__(self, addr_=0x48, i2c_=i2c):
        if _PLATFORM == 'microbit':
            self.i2c = i2c_
            self.addr = addr_
            self.i2cWrite = self.i2c.write
            self.i2cRead = self.i2c.read
        elif _PLATFORM == 'pico':
            self.i2c = i2c_
            self.addr = addr_
            self.i2cWrite = self.i2c.writeto
            self.i2cRead = self.i2c.readfrom
    
    def readTempC(self):
        self.i2cWrite(self.addr, REG_TEMPC)
        data = self.i2cRead(self.addr, 2) # returns a bytes object
        tempDataRaw = int.from_bytes(data, 'big')
        # handle negatives (MicroPython int.from_bytes does not support signed conversion (yet)
        if tempDataRaw >= 0x8000:
            return -256.0 + (tempDataRaw - 0x8000) * 7.8125e-3 # One LSB equals 7.812 mdegC
        else:
            return tempDataRaw * 7.8125e-3 # One LSB equals 7.812 mdegC