Python导入函数失败求助:调用primitives提示未定义
问题分析
Let's break down what's going wrong here and fix it step by step:
draw/device未定义:你在script1.py里直接调用primitives(device, draw)时,这两个变量只存在于script2.py的main函数内部,属于局部变量,外部脚本根本访问不到,所以必然报错。- 导入位置不合理:把
from script2 import primitives, main放在while循环里,每次循环都会重复执行导入操作,这不仅毫无必要,还可能引发重复导入的意外问题。
解决方案
根据你的需求,这里提供两种可行的修复方式:
方式一:直接复用script2的main函数(最简单)
如果你的需求只是运行OLED显示逻辑,直接调用main()就足够了——因为main函数内部已经完整包含了创建device、生成draw对象,以及调用primitives的流程。修改后的script1.py如下:
import time # 把导入放在脚本开头,只执行一次 from script2 import primitives, main variable_intermediate = 1 while True: if variable_intermediate == 1: main() # 这一行已经会执行primitives的完整逻辑 time.sleep(0.01)
方式二:单独调用primitives(自定义场景)
如果想在script1里自主控制设备和绘图逻辑,你需要像script2的main函数那样,先初始化OLED设备,再通过canvas上下文管理器生成draw对象。修改后的script1.py如下:
import time from script2 import primitives # 导入创建OLED设备所需的模块 from luma.core.interface.serial import spi from luma.core.render import canvas from luma.oled.device import ssd1351 variable_intermediate = 1 # 只初始化一次设备,避免循环里重复创建 serial = spi(device=0, port=0, gpio_DC=20) device = ssd1351(serial) device.width = 128 device.height = 128 while True: if variable_intermediate == 1: # 用with语句获取draw对象,这是luma库的标准用法 with canvas(device) as draw: primitives(device, draw) # 现在device和draw都已正确定义 time.sleep(0.01)
额外优化建议
为了让代码更易复用,你可以把script2里的设备初始化逻辑封装成单独函数:
import time import datetime from luma.core.render import canvas from luma.core.interface.serial import spi from luma.oled.device import ssd1351 def create_oled_device(): """封装OLED设备初始化逻辑,方便跨脚本复用""" serial = spi(device=0, port=0, gpio_DC=20) device = ssd1351(serial) device.width = 128 device.height = 128 return device def primitives(device, draw): # 原primitives代码保持不变 padding = 2 shape_width = 20 top = padding bottom = device.height - padding - 1 x = padding size = draw.textsize('World!') x = device.width - padding - size[0] draw.rectangle((x, top + 4, x + size[0], top + size[1]), fill="black") draw.rectangle((x, top + 16, x + size[0], top + 16 + size[1]), fill="black") draw.text((device.width - padding - size[0], top + 4), 'Hello', fill="cyan") draw.text((device.width - padding - size[0], top + 16), 'World1!', fill="purple") time.sleep(5) def main(): device = create_oled_device() print("Testing basic canvas graphics...") for _ in range(2): with canvas(device) as draw: primitives(device, draw) print("Drawing stuff 1") time.sleep(3) print("Testing clear display...") time.sleep(1) device.clear() if __name__ == "__main__": try: main() except KeyboardInterrupt: pass
之后在script1.py里就可以直接调用这个封装好的函数,不用重复写初始化代码:
import time from script2 import primitives, create_oled_device variable_intermediate = 1 device = create_oled_device() while True: if variable_intermediate == 1: with canvas(device) as draw: primitives(device, draw) time.sleep(0.01)
关键知识点回顾
- 变量作用域:函数内部定义的变量(比如
main里的device和draw)是局部变量,外部脚本无法直接访问,必须在外部重新定义或通过函数返回值获取。 - 上下文管理器(
with语句):luma库的canvas(device)必须通过with语句使用,它会自动管理draw对象的生命周期,确保绘图操作正确生效。
内容的提问来源于stack exchange,提问作者Craver2000
相关产品推荐
相关产品推荐

