You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python导入函数失败求助:调用primitives提示未定义

问题分析

Let's break down what's going wrong here and fix it step by step:

  1. draw/device未定义:你在script1.py里直接调用primitives(device, draw)时,这两个变量只存在于script2.py的main函数内部,属于局部变量,外部脚本根本访问不到,所以必然报错。
  2. 导入位置不合理:把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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:13:51