O_嵌入式专题目录

K210产品介绍

MaixPy IDE

注:以下所有MaixPy代码均基于MaixHub默认配置固件+lodepng内置模块配置。

Maix M1W Dock自检例程 - MaixPy 暂停更新

#------------------------------------------------------------------------------#
# SelfCheck_DockM1W.py - By: AaronTempletonYin - Fri Apr 9 2021
# LCD, CAM, KPU, FFT, SYS
# FPIOA, GPIO, I2C, PWM, SPI, TIMER, UART, I2S, WDT
# Freq, Reset, Utils, Video, Audio, Network

#------------------------------------------------------------------------------#
import gc, sys, os, time
from machine import Timer, UART
import Maix
from fpioa_manager import fm
from board import board_info

flagLCD = 2
flagCAM = 2
flagKPU = 2
flagFFT = 2
flagSYS = 2

flagFPIOA = 2
flagGPIO = 2
flagI2C = 2
flagPWM = 2
flagSPI = 2
flagTIMER = 2
flagUART = 2
flagI2S = 2
flagWDT = 2

flagVideo = 2
flagAudio = 2
flagNetwork = 2

# LCD -------------------------------------------------------------------------#
import lcd

def CheckList():
    global flagLCD, flagCAM, flagKPU, flagFFT, flagSYS
    global flagGPIO, flagI2C, flagPWM, flagSPI, flagTIMER, flagUART, flagI2S, flagWDT
    global flagVideo, flagAudio, flagNetwork

    lcd.fill_rectangle(10, 10, lcd.width()-20, 90, lcd.BLACK)

    if flagLCD == 0:
        lcd.draw_string(10, 10, "LCD", lcd.RED, lcd.BLACK)
    elif flagLCD == 1:
        lcd.draw_string(10, 10, "LCD", lcd.GREEN, lcd.BLACK)
    else:
        lcd.draw_string(10, 10, "LCD", lcd.WHITE, lcd.BLACK)
    if flagCAM == 0:
        lcd.draw_string(70, 10, "CAM", lcd.RED, lcd.BLACK)
    elif flagCAM == 1:
        lcd.draw_string(70, 10, "CAM", lcd.GREEN, lcd.BLACK)
    else:
        lcd.draw_string(70, 10, "CAM", lcd.WHITE, lcd.BLACK)
    if flagKPU == 0:
        lcd.draw_string(130, 10, "KPU", lcd.RED, lcd.BLACK)
    elif flagKPU == 1:
        lcd.draw_string(130, 10, "KPU", lcd.GREEN, lcd.BLACK)
    else:
        lcd.draw_string(130, 10, "KPU", lcd.WHITE, lcd.BLACK)
    if flagFFT == 0:
        lcd.draw_string(190, 10, "FFT", lcd.RED, lcd.BLACK)
    elif flagFFT == 1:
        lcd.draw_string(190, 10, "FFT", lcd.GREEN, lcd.BLACK)
    else:
        lcd.draw_string(190, 10, "FFT", lcd.WHITE, lcd.BLACK)
    if flagSYS == 0:
        lcd.draw_string(250, 10, "SYS", lcd.RED, lcd.BLACK)
    elif flagSYS == 1:
        lcd.draw_string(250, 10, "SYS", lcd.GREEN, lcd.BLACK)
    else:
        lcd.draw_string(250, 10, "SYS", lcd.WHITE, lcd.BLACK)


    if flagFPIOA == 0:
        lcd.draw_string(10, 30, "FPIOA", lcd.RED, lcd.BLACK)
    elif flagFPIOA == 1:
        lcd.draw_string(10, 30, "FPIOA", lcd.GREEN, lcd.BLACK)
    else:
        lcd.draw_string(10, 30, "FPIOA", lcd.WHITE, lcd.BLACK)
    if flagGPIO == 0:
        lcd.draw_string(70, 30, "GPIO", lcd.RED, lcd.BLACK)
    elif flagGPIO == 1:
        lcd.draw_string(70, 30, "GPIO", lcd.GREEN, lcd.BLACK)
    else:
        lcd.draw_string(70, 30, "GPIO", lcd.WHITE, lcd.BLACK)
    if flagI2C == 0:
        lcd.draw_string(130, 30, "I2C", lcd.RED, lcd.BLACK)
    elif flagI2C == 1:
        lcd.draw_string(130, 30, "I2C", lcd.GREEN, lcd.BLACK)
    else:
        lcd.draw_string(130, 30, "I2C", lcd.WHITE, lcd.BLACK)
    if flagPWM == 0:
        lcd.draw_string(190, 30, "PWM", lcd.RED, lcd.BLACK)
    elif flagPWM == 1:
        lcd.draw_string(190, 30, "PWM", lcd.GREEN, lcd.BLACK)
    else:
        lcd.draw_string(190, 30, "PWM", lcd.WHITE, lcd.BLACK)
    if flagSPI == 0:
        lcd.draw_string(250, 30, "SPI", lcd.RED, lcd.BLACK)
    elif flagSPI == 1:
        lcd.draw_string(250, 30, "SPI", lcd.GREEN, lcd.BLACK)
    else:
        lcd.draw_string(250, 30, "SPI", lcd.WHITE, lcd.BLACK)
    if flagTIMER == 0:
        lcd.draw_string(10, 50, "TIMER", lcd.RED, lcd.BLACK)
    elif flagTIMER == 1:
        lcd.draw_string(10, 50, "TIMER", lcd.GREEN, lcd.BLACK)
    else:
        lcd.draw_string(10, 50, "TIMER", lcd.WHITE, lcd.BLACK)
    if flagUART == 0:
        lcd.draw_string(70, 50, "UART", lcd.RED, lcd.BLACK)
    elif flagUART == 1:
        lcd.draw_string(70, 50, "UART", lcd.GREEN, lcd.BLACK)
    else:
        lcd.draw_string(70, 50, "UART", lcd.WHITE, lcd.BLACK)
    if flagI2S == 0:
        lcd.draw_string(130, 50, "I2S", lcd.RED, lcd.BLACK)
    elif flagI2S == 1:
        lcd.draw_string(130, 50, "I2S", lcd.GREEN, lcd.BLACK)
    else:
        lcd.draw_string(130, 50, "I2S", lcd.WHITE, lcd.BLACK)
    if flagWDT == 0:
        lcd.draw_string(190, 50, "WDT", lcd.RED, lcd.BLACK)
    elif flagWDT == 1:
        lcd.draw_string(190, 50, "WDT", lcd.GREEN, lcd.BLACK)
    else:
        lcd.draw_string(190, 50, "WDT", lcd.WHITE, lcd.BLACK)

    if flagVideo == 0:
        lcd.draw_string(10, 70, "Video", lcd.RED, lcd.BLACK)
    elif flagVideo == 1:
        lcd.draw_string(10, 70, "Video", lcd.GREEN, lcd.BLACK)
    else:
        lcd.draw_string(10, 70, "Video", lcd.WHITE, lcd.BLACK)
    if flagAudio == 0:
        lcd.draw_string(70, 70, "Audio", lcd.RED, lcd.BLACK)
    elif flagAudio == 1:
        lcd.draw_string(70, 70, "Audio", lcd.GREEN, lcd.BLACK)
    else:
        lcd.draw_string(70, 70, "Audio", lcd.WHITE, lcd.BLACK)
    if flagNetwork == 0:
        lcd.draw_string(130, 70, "Network", lcd.RED, lcd.BLACK)
    elif flagNetwork == 1:
        lcd.draw_string(130, 70, "Network", lcd.GREEN, lcd.BLACK)
    else:
        lcd.draw_string(130, 70, "Network", lcd.WHITE, lcd.BLACK)


def DisplayFor(seconds, height):
    for i in range(seconds):
        lcd.fill_rectangle(10, height, lcd.width()-20, 20, lcd.BLACK)
        lcd.draw_string(145, height, "{}".format(seconds-i), lcd.WHITE, lcd.BLACK)
        time.sleep(1)


def InitLCD():
    # "color=lcd.RGB565" in default
    lcd.init(freq=15000000)
    # Rotation 0-3
    lcd.rotation(0)

def CheckLCD():
    global flagLCD
    InitLCD()
    lcd.fill_rectangle(10, 130, lcd.width()-20, 60, lcd.BLACK)
    lcd.draw_string(100, 130, "LCD init done.", lcd.WHITE, lcd.BLACK)
    flagLCD = 1
    CheckList()

# CAM TIMER -------------------------------------------------------------------#
import sensor, image

def onCamTimer(timerC):
    global camCount
    camCount += 1
    print('S: ', camCount)

camCount = 0
camTimer = Timer(Timer.TIMER0, Timer.CHANNEL0, mode=Timer.MODE_PERIODIC, period=1, unit=Timer.UNIT_S, callback=onCamTimer, arg=None, start=False, priority=1, div=0)

def InitCAM():
    lcd.fill_rectangle(10, 130, lcd.width()-20, 60, lcd.BLACK)
    lcd.draw_string(80, 130, "Init CAM & TIMER ...", lcd.WHITE, lcd.BLACK)
    sensor.reset(freq=20000000, dual_buff=True)
    sensor.set_pixformat(sensor.RGB565)
    sensor.set_framesize(sensor.QVGA)
    sensor.skip_frames()
    #sensor.set_hmirror(True)
    sensor.set_vflip(True)

def CheckCAMandTIMER():
    global camCount, flagCAM, flagTIMER
    InitCAM()
    lcd.fill_rectangle(10, 130, lcd.width()-20, 60, lcd.BLACK)
    lcd.draw_string(110, 130, "CAM id: %x" % sensor.get_id(), lcd.WHITE, lcd.BLACK)
    lcd.draw_string(95, 150, "TIMER time: 5s", lcd.WHITE, lcd.BLACK)
    time.sleep(3)
    camCount = 0
    camTimer.start()
    #sensor.set_contrast(0)
    #sensor.set_brightness(0)
    #sensor.set_auto_gain(1)

    while 1:
        if camCount >5:
            sensor.run(0)
            # Shutdown the camera if enable is False
            sensor.shutdown(False)
            lcd.clear()
            camTimer.stop()
            flagCAM = 1
            flagTIMER = 1
            CheckList()
            lcd.fill_rectangle(10, 130, lcd.width()-20, 60, lcd.BLACK)
            lcd.draw_string(70, 130, "CAM & TIMER test done.", lcd.WHITE, lcd.BLACK)
            break
        img = sensor.snapshot()
        lcd.display(img)









#import KPU as KPU

# SYS -------------------------------------------------------------------------#
def CheckSYS():
    global flagSYS
    lcd.fill_rectangle(10, 130, lcd.width()-20, 60, lcd.BLACK)
    lcd.draw_string(70, 130, "CPU frequence: {} MHz".format(Maix.freq.get_cpu()), lcd.WHITE, lcd.BLACK)
    lcd.draw_string(70, 150, "KPU frequence: {} MHz".format(Maix.freq.get_kpu()), lcd.WHITE, lcd.BLACK)
    lcd.draw_string(90, 170, "Heap size: {}".format(Maix.utils.gc_heap_size()), lcd.WHITE, lcd.BLACK)
    flagSYS = 1
    CheckList()

# FPIOA GPIO ------------------------------------------------------------------#
def onLedTimer(timerL):
    global ledState
    #print(ledState)
    if ledState == 1:
        ledState += 1
        ledRDock.value(0)
        ledGDock.value(1)
        ledBDock.value(1)
    elif ledState == 2:
        ledState += 1
        ledRDock.value(1)
        ledGDock.value(0)
        ledBDock.value(1)
    elif ledState == 3:
        ledState += 1
        ledRDock.value(1)
        ledGDock.value(1)
        ledBDock.value(0)
    elif ledState == 4:
        ledState += 1
        ledRDock.value(0)
        ledGDock.value(0)
        ledBDock.value(1)
    elif ledState == 5:
        ledState += 1
        ledRDock.value(0)
        ledGDock.value(1)
        ledBDock.value(0)
    elif ledState == 6:
        ledState += 1
        ledRDock.value(1)
        ledGDock.value(0)
        ledBDock.value(0)
    elif ledState == 7:
        ledState += 1
        ledRDock.value(0)
        ledGDock.value(0)
        ledBDock.value(0)
    else:
        ledState = 1
        ledRDock.value(1)
        ledGDock.value(1)
        ledBDock.value(1)

fm.register(12, fm.fpioa.GPIO1)
ledBDock = Maix.GPIO(Maix.GPIO.GPIO1, Maix.GPIO.OUT)
ledBDock.value(1)
fm.register(13, fm.fpioa.GPIO2)
ledGDock = Maix.GPIO(Maix.GPIO.GPIO2, Maix.GPIO.OUT)
ledGDock.value(1)
fm.register(14, fm.fpioa.GPIO3)
ledRDock = Maix.GPIO(Maix.GPIO.GPIO3, Maix.GPIO.OUT)
ledRDock.value(1)
ledState = 1
ledTimer = Timer(Timer.TIMER1, Timer.CHANNEL0, mode=Timer.MODE_PERIODIC, period=1, unit=Timer.UNIT_S, callback=onLedTimer, arg=None, start=False, priority=1, div=0)

def CheckFPIOAandGPIO():
    global flagFPIOA, flagGPIO
    ledTimer.start()
    lcd.fill_rectangle(10, 130, lcd.width()-20, 60, lcd.BLACK)
    lcd.draw_string(70, 130, "FPIOA & GPIO init done.", lcd.WHITE, lcd.BLACK)
    lcd.draw_string(76, 150, "Please check RGB led.", lcd.WHITE, lcd.BLACK)
    flagFPIOA = 1
    flagGPIO = 1
    CheckList()
    DisplayFor(8, 170)
    ledTimer.stop()
    ledRDock.value(1)
    ledGDock.value(1)
    ledBDock.value(1)




def MainCheck():
    CheckLCD()
    DisplayFor(1, 150)
    #CheckCAMandTIMER()
    #CheckSYS()
    CheckFPIOAandGPIO()

MainCheck()

Maix M1W Dock人脸识别例程 - MaixPy

注意烧录的MaixPy固件必须支持kmodel。
import sensor
import image
import lcd
import KPU as kpu
import time
from Maix import FPIOA, GPIO
import gc
from fpioa_manager import fm
from board import board_info
import utime

# Sipeed offical demo, flash to SPIFFS, see https://www.maixhub.com/modelInfo?modelId=14
#task_fd = kpu.load(0x300000)
#task_ld = kpu.load(0x400000)
#task_fe = kpu.load(0x500000)

# Put models to SD card, notice that the filename must be correct
task_fd = kpu.load("/sd/FaceDetection.smodel")
task_ld = kpu.load("/sd/FaceLandmarkDetection.smodel")
task_fe = kpu.load("/sd/FeatureExtraction.smodel")

clock = time.clock()

fm.register(board_info.BOOT_KEY, fm.fpioa.GPIOHS0)
key_gpio = GPIO(GPIO.GPIOHS0, GPIO.IN)
start_processing = False

BOUNCE_PROTECTION = 50

def set_key_state(*_):
    global start_processing
    start_processing = True
    utime.sleep_ms(BOUNCE_PROTECTION)

key_gpio.irq(set_key_state, GPIO.IRQ_RISING, GPIO.WAKEUP_NOT_SUPPORT)

lcd.init()
sensor.reset(dual_buff=True)
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.set_hmirror(1)
sensor.set_vflip(1)
sensor.run(1)
anchor = (1.889, 2.5245, 2.9465, 3.94056, 3.99987, 5.3658, 5.155437,
          6.92275, 6.718375, 9.01025)  # anchor for face detect
dst_point = [(44, 59), (84, 59), (64, 82), (47, 105),
             (81, 105)]  # standard face key point position
a = kpu.init_yolo2(task_fd, 0.5, 0.3, 5, anchor)
img_lcd = image.Image()
img_face = image.Image(size=(128, 128))
a = img_face.pix_to_ai()
record_ftr = []
record_ftrs = []
names = ['Mr.1', 'Mr.2', 'Mr.3', 'Mr.4', 'Mr.5',
         'Mr.6', 'Mr.7', 'Mr.8', 'Mr.9', 'Mr.10']

ACCURACY = 85

while (1):
    img = sensor.snapshot()
    clock.tick()
    code = kpu.run_yolo2(task_fd, img)
    if code:
        for i in code:
            # Cut face and resize to 128x128
            a = img.draw_rectangle(i.rect())
            face_cut = img.cut(i.x(), i.y(), i.w(), i.h())
            face_cut_128 = face_cut.resize(128, 128)
            a = face_cut_128.pix_to_ai()
            # a = img.draw_image(face_cut_128, (0,0))
            # Landmark for face 5 points
            fmap = kpu.forward(task_ld, face_cut_128)
            plist = fmap[:]
            le = (i.x() + int(plist[0] * i.w() - 10), i.y() + int(plist[1] * i.h()))
            re = (i.x() + int(plist[2] * i.w()), i.y() + int(plist[3] * i.h()))
            nose = (i.x() + int(plist[4] * i.w()), i.y() + int(plist[5] * i.h()))
            lm = (i.x() + int(plist[6] * i.w()), i.y() + int(plist[7] * i.h()))
            rm = (i.x() + int(plist[8] * i.w()), i.y() + int(plist[9] * i.h()))
            a = img.draw_circle(le[0], le[1], 4)
            a = img.draw_circle(re[0], re[1], 4)
            a = img.draw_circle(nose[0], nose[1], 4)
            a = img.draw_circle(lm[0], lm[1], 4)
            a = img.draw_circle(rm[0], rm[1], 4)
            # align face to standard position
            src_point = [le, re, nose, lm, rm]
            T = image.get_affine_transform(src_point, dst_point)
            a = image.warp_affine_ai(img, img_face, T)
            a = img_face.ai_to_pix()
            # a = img.draw_image(img_face, (128,0))
            del (face_cut_128)
            # calculate face feature vector
            fmap = kpu.forward(task_fe, img_face)
            feature = kpu.face_encode(fmap[:])
            reg_flag = False
            scores = []
            for j in range(len(record_ftrs)):
                score = kpu.face_compare(record_ftrs[j], feature)
                scores.append(score)
            max_score = 0
            index = 0
            for k in range(len(scores)):
                if max_score < scores[k]:
                    max_score = scores[k]
                    index = k
            if max_score > ACCURACY:
                a = img.draw_string(i.x(), i.y(), ("%s :%2.1f" % (
                    names[index], max_score)), color=(0, 255, 0), scale=2)
            else:
                a = img.draw_string(i.x(), i.y(), ("X :%2.1f" % (
                    max_score)), color=(255, 0, 0), scale=2)
            if start_processing:
                record_ftr = feature
                record_ftrs.append(record_ftr)
                start_processing = False

            break
    fps = clock.fps()
    print("%2.1f fps" % fps)
    a = lcd.display(img)
    gc.collect()
    # kpu.memtest()

# a = kpu.deinit(task_fe)
# a = kpu.deinit(task_ld)
# a = kpu.deinit(task_fd)

Kendeyte IDE

其它

错误集锦

  • OSError: no available NIC

    没有连接网络。

MaixPy内部定义视频尺寸

  • (实测Camera只能用QVGA。)

    typedef enum {
      FRAMESIZE_INVALID = 0,
      // C/SIF Resolutions
      FRAMESIZE_QQCIF, // 88x72
      FRAMESIZE_QCIF, // 176x144
      FRAMESIZE_CIF, // 352x288
      FRAMESIZE_QQSIF, // 88x60
      FRAMESIZE_QSIF, // 176x120
      FRAMESIZE_SIF, // 352x240
      // VGA Resolutions
      FRAMESIZE_QQQQVGA, // 40x30
      FRAMESIZE_QQQVGA, // 80x60
      FRAMESIZE_QQVGA, // 160x120
      FRAMESIZE_QVGA, // 320x240
      FRAMESIZE_VGA, // 640x480
      FRAMESIZE_HQQQVGA, // 60x40
      FRAMESIZE_HQQVGA, // 120x80
      FRAMESIZE_HQVGA, // 240x160
      // FFT Resolutions
      FRAMESIZE_64X32, // 64x32
      FRAMESIZE_64X64, // 64x64
      FRAMESIZE_128X64, // 128x64
      FRAMESIZE_128X128, // 128x128
      FRAMESIZE_240X240, // 240x240
      // Other
      FRAMESIZE_LCD, // 128x160
      FRAMESIZE_QQVGA2, // 128x160
      FRAMESIZE_WVGA, // 720x480
      FRAMESIZE_WVGA2, // 752x480
      FRAMESIZE_SVGA, // 800x600
      FRAMESIZE_SXGA, // 1280x1024
      FRAMESIZE_UXGA, // 1600x1200
    } framesize_t;

ESPAT库

注:实际使用时http获取返回头会很慢,有待优化。
from network_espat import wifi
def EspatInit():
    if LCD_DEBUG == 1:
        lcd.clear()
        lcd.rotation(1)
        lcd.draw_string(50, 150, "Network initing ...", lcd.WHITE, lcd.BLACK)
    SSID = "K210T"
    PASW = "00000000"
    if wifi.isconnected() == False:
        for i in range(5):
            try:
                wifi.reset()
                print(wifi.at_cmd("AT\r\n"))
                print(wifi.at_cmd("AT+GMR\r\n"))
                print("STA mode: ", wifi._at_cmd("AT+CWMODE_DEF=1\r\n"))
                print("Auto connect: ", wifi._at_cmd("AT+CWAUTOCONN=1\r\n"))
                print(wifi.at_cmd("AT+CIPSTATUS\r\n"))
                print("Try AT connect wifi ...", wifi._at_cmd())
                if LCD_DEBUG == 1:
                    lcd.clear()
                    lcd.draw_string(30, 150, "Try AT connect wifi ...", lcd.WHITE, lcd.BLACK)
                    lcd.draw_string(110, 170, "{}".format(5-i), lcd.WHITE, lcd.BLACK)
                wifi.connect(SSID, PASW)
                if wifi.isconnected():
                    break
            except Exception as e:
                print(e)

    if wifi.isconnected() == True:
        print("Network state: {} - {} - {}".format(wifi.isconnected(), wifi.ifconfig()[6], wifi.ifconfig()[0]))
        if LCD_DEBUG == 1:
            lcd.clear()
            lcd.draw_string(65, 130, "Network state:", lcd.WHITE, lcd.BLACK)
            lcd.draw_string(65, 150, "{}".format(wifi.ifconfig()[6]), lcd.WHITE, lcd.BLACK)
            lcd.draw_string(65, 170, "{}".format(wifi.ifconfig()[0]), lcd.WHITE, lcd.BLACK)

MQTT库

from umqtt_simple import MQTTClient
def mqttCallback(topic, msg):
    print((topic, msg))
    lcd.fill_rectangle(10, 180, lcd.width()-20, 20, lcd.BLACK)
    lcd.draw_string(35, 180, ": %s" % msg, lcd.WHITE, lcd.BLACK)

    if topic != b'':
        lcd.fill_rectangle(10, 150, lcd.width()-20, 20, lcd.BLACK)
        lcd.draw_string(35, 150, "Subscribe to %s" % topic, lcd.WHITE, lcd.BLACK)

mqttClientId = "7d54f85af42976ee3c2693e6xxxxxxxx"
mqttServer = "bemfa.com"
mqttPort = 9501
mqttTopic = b"K210T1"
mqttC = MQTTClient(mqttClientId, mqttServer, mqttPort)
def MqttInit():
    if LCD_DEBUG == 1:
        lcd.clear()
        lcd.draw_string(70, 10, "{}".format(wifi.ifconfig()[0]), lcd.WHITE, lcd.BLACK)
        lcd.draw_string(50, 150, "Mqtt connecting ...", lcd.WHITE, lcd.BLACK)
    mqttC.set_callback(mqttCallback)
    mqttC.connect()
    mqttC.subscribe(mqttTopic, qos=0)
    print("Connected to %s:%s, subscribed to %s topic." % (mqttServer, mqttPort, mqttTopic))
    mqttC.publish(mqttTopic, b"K210T1 online.")
    if LCD_DEBUG == 1:
        lcd.fill_rectangle(10, 150, lcd.width()-20, 20, lcd.BLACK)
        lcd.draw_string(65, 150, "Mqtt connected.", lcd.WHITE, lcd.BLACK)

    while 1:
        if 0:
            # Blocking wait for message
            mqttC.wait_msg()
        else:
            # Non-blocking wait for message
            mqttC.check_msg()
            # Then need to sleep to avoid 100% CPU usage (in a real
            # app other useful actions would be performed instead)
            time.sleep(1)
    mqttC.disconnect()

local variable xxx referenced before assignment

  在Python中有一个经典错误:

local variable xxx referenced before assignment
 #赋值前引用的局部变量xxx

  这里引入两个概念:

  局部变量指的在函数内部定义并使用的变量,它只在函数内部有效。
  全局变量指的是能作用于函数内外的变量,即全局变量既可以在各个函数的外部使用,也可以在各函数内部使用。
  • Test_1:
def main():
    num=5
    print(num)
main()
print(num)
#NameError: name 'num' is not defined

  这里是提示num没有被定义,因为num属于在main函数内部的变量,在函数体外面是不会被调用,解释器也不会认识这个num变量,只有当main函数调用时,才可以获得其内部一些变量,这就是局部变量。

def main():
    global num
    num=5
    print(num)
main()
print(num)

  使用global声明num为全局变量就可以了,但是应当注意,在项目中,定义全局变量会造成进程死锁。

  • Test_2:
num=10
def main():
    print(num)
    num=5
    print(num)
main()
print(num)
UnboundLocalError: local variable 'num' referenced before assignment

  这就是赋前引用局部变量,num在main函数外界定义一次,但在main函数内部又定义一次,python将优先处理在函数体内的变量,且调用在定义之前,所以在第三行print(num)报错,后面num变量赋值num=5让num=10失去全局效果。

  • Test_3:
global num
num=10
def main():
    print(num)
    num=5
    print('main:{}'.format(num))
main()
print(num)

  声明num 为全局变量后,依然报错赋前引用局部变量,则就进一步说明在函数体内部自称一体,num为全局变量,只能保证在函数体内部认识这个num变量,但在函数体内部对num变量进行的改变,依然要保证先赋值后调用。

global num
num=10
def main():
    #print(num)
    num=5
    print('main:{}'.format(num))
main()
print(num)
main:5
10
global num
num=10
def main():
    #print(num)
    #num=5
    print('main:{}'.format(num))
main()
print(num)
main:10
10
num=10
def main():
    global num
    print(num)
    num=5
    print('main:{}'.format(num))
main()
print('外部:{}'.format(num))
10
main:5
外部:5

  可以通过三个例子进一步总结。

  Python 命名空间查找顺序:
  假设我们要使用变量 runoob,则 Python 的查找顺序为:局部的命名空间去 -> 全局命名空间 -> 内置命名空间。
  如果找不到变量 runoob,它将放弃查找并引发一个 NameError 异常:NameError: name ‘runoob’ is not defined

  在实际运用中:

@app.route('/',methods=['GET','POST'])
def index():
    if request.method == 'POST':
            text='你好'
            #return render_template('index.html',text=text)
    return render_template('index.html',text=text)

  在flask中text传入前端,就会报错 local variable text referenced before assignment,解决方案就是取消注释那一句,讲最后一句text删除。
  实际上这个错误可以归结于变量作用域问题,参考文章:https://www.cnblogs.com/fireporsche/p/7813961.html

版权声明:本文为CSDN博主「菜鸟上路_lbz」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_44198436/article/details/100051651

评论已关闭

Loading...
Fullscreen Image