Python, cannot import name

匿名 (未验证) 提交于 2019-12-03 01:29:01

问题:

I have 3 files lcdtest.py, lcd.py and alarmfunctionr.py. I am trying to control the attached lcd display on my raspberry pi with the lcdtest.py script.

!/usr/bin/env python import paho.mqtt.client as paho import globals import time from alarmfunctionsr import SendToLCD from lcd import noDisplay from lcd import message  globals.init()  SendToLCD(12, "test lcd" ,1) #Test time.sleep(5)  lcd.message("test with message") time.sleep(5)  noDisplay 

The import from alarmfunctionsr seem to work ok but i get an cannot import name error when i try the same for the lcd script.

lcd.py:

#!/usr/bin/python  # # based on code from lrvick and LiquidCrystal # lrvic - https://github.com/lrvick/raspi-hd44780/blob/master/hd44780.py # LiquidCrystal - https://github.com/arduino/Arduino/blob/master/libraries/LiquidCrystal/LiquidCrystal.cpp #  from time import sleep   class CharLCD(object):      # commands     LCD_CLEARDISPLAY        = 0x01     LCD_RETURNHOME          = 0x02     LCD_ENTRYMODESET        = 0x04     LCD_DISPLAYCONTROL      = 0x08     LCD_CURSORSHIFT         = 0x10     LCD_FUNCTIONSET         = 0x20     LCD_SETCGRAMADDR        = 0x40     LCD_SETDDRAMADDR        = 0x80      # flags for display entry mode     LCD_ENTRYRIGHT          = 0x00     LCD_ENTRYLEFT           = 0x02     LCD_ENTRYSHIFTINCREMENT = 0x01     LCD_ENTRYSHIFTDECREMENT = 0x00      # flags for display on/off control     LCD_DISPLAYON           = 0x04     LCD_DISPLAYOFF          = 0x00     LCD_CURSORON            = 0x02     LCD_CURSOROFF           = 0x00     LCD_BLINKON             = 0x01     LCD_BLINKOFF            = 0x00      # flags for display/cursor shift     LCD_DISPLAYMOVE         = 0x08     LCD_CURSORMOVE          = 0x00      # flags for display/cursor shift     LCD_DISPLAYMOVE         = 0x08     LCD_CURSORMOVE          = 0x00     LCD_MOVERIGHT           = 0x04     LCD_MOVELEFT            = 0x00      # flags for function set     LCD_8BITMODE            = 0x10     LCD_4BITMODE            = 0x00     LCD_2LINE               = 0x08     LCD_1LINE               = 0x00     LCD_5x10DOTS            = 0x04     LCD_5x8DOTS             = 0x00      def __init__(self, pin_rs=25, pin_e=24, pins_db=[23, 17, 27, 22], GPIO=None):         # Emulate the old behavior of using RPi.GPIO if we haven't been given         # an explicit GPIO interface to use         if not GPIO:             import RPi.GPIO as GPIO             GPIO.setwarnings(False)         self.GPIO = GPIO         self.pin_rs = pin_rs         self.pin_e = pin_e         self.pins_db = pins_db          self.GPIO.setmode(GPIO.BCM)         self.GPIO.setup(self.pin_e, GPIO.OUT)         self.GPIO.setup(self.pin_rs, GPIO.OUT)          for pin in self.pins_db:             self.GPIO.setup(pin, GPIO.OUT)          self.write4bits(0x33)  # initialization         self.write4bits(0x32)  # initialization         self.write4bits(0x28)  # 2 line 5x7 matrix         self.write4bits(0x0C)  # turn cursor off 0x0E to enable cursor         self.write4bits(0x06)  # shift cursor right          self.displaycontrol = self.LCD_DISPLAYON | self.LCD_CURSOROFF | self.LCD_BLINKOFF          self.displayfunction = self.LCD_4BITMODE | self.LCD_1LINE | self.LCD_5x8DOTS         self.displayfunction |= self.LCD_2LINE          # Initialize to default text direction (for romance languages)         self.displaymode = self.LCD_ENTRYLEFT | self.LCD_ENTRYSHIFTDECREMENT         self.write4bits(self.LCD_ENTRYMODESET | self.displaymode)  # set the entry mode          self.clear()      def begin(self, cols, lines):         if (lines > 1):             self.numlines = lines             self.displayfunction |= self.LCD_2LINE      def home(self):         self.write4bits(self.LCD_RETURNHOME)  # set cursor position to zero         self.delayMicroseconds(3000)  # this command takes a long time!      def clear(self):         self.write4bits(self.LCD_CLEARDISPLAY)  # command to clear display         self.delayMicroseconds(3000)  # 3000 microsecond sleep, clearing the display takes a long time      def setCursor(self, col, row):         self.row_offsets = [0x00, 0x40, 0x14, 0x54]         self.write4bits(self.LCD_SETDDRAMADDR | (col + self.row_offsets[row]))      def noDisplay(self):         """ Turn the display off (quickly) """         self.displaycontrol &= ~self.LCD_DISPLAYON         self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)      def display(self):         """ Turn the display on (quickly) """         self.displaycontrol |= self.LCD_DISPLAYON         self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)      def noCursor(self):         """ Turns the underline cursor off """         self.displaycontrol &= ~self.LCD_CURSORON         self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)      def cursor(self):         """ Turns the underline cursor on """         self.displaycontrol |= self.LCD_CURSORON         self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)      def noBlink(self):         """ Turn the blinking cursor off """         self.displaycontrol &= ~self.LCD_BLINKON         self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)      def blink(self):         """ Turn the blinking cursor on """         self.displaycontrol |= self.LCD_BLINKON         self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)      def DisplayLeft(self):         """ These commands scroll the display without changing the RAM """         self.write4bits(self.LCD_CURSORSHIFT | self.LCD_DISPLAYMOVE | self.LCD_MOVELEFT)      def scrollDisplayRight(self):         """ These commands scroll the display without changing the RAM """         self.write4bits(self.LCD_CURSORSHIFT | self.LCD_DISPLAYMOVE | self.LCD_MOVERIGHT)      def leftToRight(self):         """ This is for text that flows Left to Right """         self.displaymode |= self.LCD_ENTRYLEFT         self.write4bits(self.LCD_ENTRYMODESET | self.displaymode)      def rightToLeft(self):         """ This is for text that flows Right to Left """         self.displaymode &= ~self.LCD_ENTRYLEFT         self.write4bits(self.LCD_ENTRYMODESET | self.displaymode)      def autoscroll(self):         """ This will 'right justify' text from the cursor """         self.displaymode |= self.LCD_ENTRYSHIFTINCREMENT         self.write4bits(self.LCD_ENTRYMODESET | self.displaymode)      def noAutoscroll(self):         """ This will 'left justify' text from the cursor """         self.displaymode &= ~self.LCD_ENTRYSHIFTINCREMENT         self.write4bits(self.LCD_ENTRYMODESET | self.displaymode)      def write4bits(self, bits, char_mode=False):         """ Send command to LCD """         self.delayMicroseconds(1000)  # 1000 microsecond sleep         bits = bin(bits)[2:].zfill(8)         self.GPIO.output(self.pin_rs, char_mode)         for pin in self.pins_db:             self.GPIO.output(pin, False)         for i in range(4):             if bits[i] == "1":                 self.GPIO.output(self.pins_db[::-1][i], True)         self.pulseEnable()         for pin in self.pins_db:             self.GPIO.output(pin, False)         for i in range(4, 8):             if bits[i] == "1":                 self.GPIO.output(self.pins_db[::-1][i-4], True)         self.pulseEnable()      def delayMicroseconds(self, microseconds):         seconds = microseconds / float(1000000)  # divide microseconds by 1 million for seconds         sleep(seconds)      def pulseEnable(self):         self.GPIO.output(self.pin_e, False)         self.delayMicroseconds(1)       # 1 microsecond pause - enable pulse must be > 450ns         self.GPIO.output(self.pin_e, True)         self.delayMicroseconds(1)       # 1 microsecond pause - enable pulse must be > 450ns         self.GPIO.output(self.pin_e, False)         self.delayMicroseconds(1)       # commands need > 37us to settle      def message(self, text):         """ Send string to LCD. Newline wraps to second line"""         for char in text:             if char == '\n':                 self.write4bits(0xC0)  # next line             else:                 self.write4bits(ord(char), True)  def DisplayLCD(msg):     lcd = CharLCD()     lcd.clear()     x=msg.find("**")     if x>0:         line1=msg[0:x]         line2=msg[x+2:len(msg)]     else:         line1=msg         line2=""     lcd.message(line1+"\n"+line2) 

alarmfunctionsr.py:

#!/usr/bin/env python """   import globals import urllib2 import smtplib import serial import time import sys import thread import RPi.GPIO as GPIO import os, glob, time, operator from email.mime.text import MIMEText from email.mime.application import MIMEApplication from email.mime.multipart import MIMEMultipart from time import sleep  def find_all(a_str, sub):         start = 0         cnt=0         while True:                 start = a_str.find(sub, start)                 if start == -1:                          return cnt                 start += len(sub)                 cnt=cnt+1  def isNumber(x):         # Test whether the contents of a string is a number         try:                 val = int(x)         except ValueError:                 return False         return True  def get_latest_photo(files):     lt = operator.lt     if not files:         return None     now = time.time()     latest = files[0], now - os.path.getctime(files[0])     for f in files[1:]:         age = now - os.path.getctime(f)         if lt(age, latest[1]):             latest = f, age     return latest[0]  def UpdateHostThread(function,opcode):         try:                 thread.start_new_thread(UpdateHostThread, (function,opcode, ) )         except:                 print "Error: unable to start thread"  def UpdateHost(function,opcode):         # Sends data to the server          script_path = "https://www.privateeyepi.com/alarmhostr.php?u="+globals.user+"&p="+globals.password+"&function="+str(function)          i=0         for x in opcode:                 script_path=script_path+"&opcode"+str(i)+"="+str(opcode[i])                 i=i+1          if globals.PrintToScreen: print "Host Update: "+script_path          try:                 rt=urllib2.urlopen(script_path)         except urllib2.HTTPError:                 if globals.PrintToScreen: print "HTTP Error"                 return False         time.sleep(.2)         temp=rt.read()         if globals.PrintToScreen: print temp         l = find_all(temp,"/n");         RecordSet = temp.split(',')         c=[]         y=0         c.append([])         for x in RecordSet:                 if x=="/n":                         y=y+1                         if y < l:                                 c.append([])                 else:                         if isNumber(x):                                 c[y].append(int(x))                         else:                                 c[y].append(x)         rt=ProcessActions(c)         if rt==False:                 return(False)         else:             return(c)  def ProcessActions(ActionList):         FalseInd=True         for x in ActionList:             if x[0]=="/EMAIL":                     SendEmailAlertFromRule(x[1], x[2],0)                     x.remove             if x[0]=="/SEMAIL":                     SendEmailAlert(x[1])                     x.remove             if x[0]=="/CHIME":                     StartChimeThread()                     x.remove             if x[0]=="/rn588":                     exit()             if x[0]=="/FALSE":                     FalseInd=False             if x[0]=="/SIREN":                     StartSirenThread(x[2])                     x.remove             if x[0]=="/PHOTO":                     SendEmailAlertFromRule(x[1], x[2],1)                     x.remove             if x[0]=="/RELAYON":                     SwitchRelay(1)                     x.remove             if x[0]=="/RELAYOFF":                     SwitchRelay(0)                     x.remove             if x[0]=="/WRELAYON":                     SwitchRFRelay(1)                     x.remove             if x[0]=="/WRELAYOFF":                     SwitchRFRelay(0)                     x.remove         return(FalseInd)  def StartSirenThread(Zone):         try:                 thread.start_new_thread(Siren, (Zone, ) )         except:                 print "Error: unable to start thread"  def SwitchRelay(onoff):         GPIO.setmode(GPIO.BOARD)         GPIO.setup(globals.RelayPin, GPIO.OUT)          GPIO.output(globals.RelayPin,onoff)  def SwitchRFRelay(onoff):         # declare to variables, holding the com port we wish to talk to and the speed         port = '/dev/ttyAMA0'         baud = 9600          # open a serial connection using the variables above         ser = serial.Serial(port=port, baudrate=baud)          # wait for a moment before doing anything else         sleep(0.2)          for i in range(0,3):                 if (onoff==True):                                ser.write('a{}RELAYAON-'.format(globals.WRelayPin))                 else:                         ser.write('a{}RELAYAOFF'.format(globals.WRelayPin))                 time.sleep(2)         ser.close  def SendToLCD(GPIOnumber, Location, status):     import paho.mqtt.client as paho     if status==0:             ActionStr="_"             topic="alarm_activity"     else:             if status==1:                     ActionStr="_"                     topic="alarm_activity"             else:                     topic="temperature"                     if status==2:                             ActionStr=str(GPIOnumber)+","+Location                     else:                             ActionStr="Undefined"      #client = mosquitto.Mosquitto('privateeyepi')     client = paho.Client()     client.connect(globals.lcd_ip)     if status <= 1:             if globals.PrintToScreen:                     print str(Location)+"**"+str(ActionStr)             client.publish(topic, str(Location)+"**"+str(ActionStr))     else:                 if globals.PrintToScreen:                     print str(ActionStr)             client.publish(topic, ActionStr)     client.disconnect()          def Siren(Zone):         GPIO.setmode(GPIO.BOARD)         if globals.UseSiren == True:                 GPIO.setup(globals.SirenGPIOPin, GPIO.OUT) #Siren pin setup         else:                 return          if globals.SirenDelay>0:                 globals.SirenStartTime = time.time()                 while time.time() < globals.SirenStartTime + globals.SirenDelay:                         if globals.BeepDuringDelay:                                 GPIO.output(globals.SirenGPIOPin,True)                                 time.sleep(1)                                 GPIO.output(globals.SirenGPIOPin,False)                                 time.sleep(4)          GPIO.output(globals.SirenGPIOPin,True)         globals.SirenStartTime = time.time()         if globals.PrintToScreen: print "Siren Activated"         while time.time() < globals.SirenStartTime + globals.SirenTimeout:                 time.sleep(5)                 if CheckForSirenDeactivation(Zone) == True:                         break         GPIO.output(globals.SirenGPIOPin,False)         if globals.PrintToScreen: print "Siren Deactivated"  def CheckForSirenDeactivation(Zone):         # Routine to fetch the location and zone descriptions from the server          RecordSet = GetDataFromHost(16,[Zone])         if globals.PrintToScreen: print RecordSet         ZoneStatus=RecordSet[0][0]         if ZoneStatus=="FALSE":                 return (True)      def StartChimeThread():         try:                 thread.start_new_thread(SoundChime, ())         except:                 print "Error: unable to start thread"  def SoundChime():         if globals.ChimeDuration>0:                 GPIO.setmode(GPIO.BOARD)                 GPIO.setup(globals.ChimeGPIOPin, GPIO.OUT) #Siren pin setup                 GPIO.output(globals.ChimeGPIOPin,True)                 time.sleep(globals.ChimeDuration)                 GPIO.output(globals.ChimeGPIOPin,False)  def GetDataFromHost(function,opcode): # Request data and receive reply (request/reply) from the server          script_path = "https://www.privateeyepi.com/alarmhostr.php?u="+globals.user+"&p="+globals.password+"&function="+str(function)          i=0         for x in opcode:                 script_path=script_path+"&opcode"+str(i)+"="+str(opcode[i])                 i=i+1          if globals.PrintToScreen: print script_path          try:                 rt = urllib2.urlopen(script_path)         except urllib2.HTTPError:                 return False         temp=rt.read()         if globals.PrintToScreen: print temp          l = find_all(temp,"/n");         RecordSet = temp.split(',')         c=[]         y=0         c.append([])         for x in RecordSet:                 if x=="/n":                         y=y+1                         if y < l:                                 c.append([])                 else:                         if isNumber(x):                                 c[y].append(int(x))                         else:                                 c[y].append(x)         rt=ProcessActions(c)            if rt==False:                 return(False)         else:             return(c)          return(c)  def BuildMessage(SensorNumber):         # Routine to fetch the location and zone descriptions from the server            RecordSet = GetDataFromHost(6,[SensorNumber])         if globals.PrintToScreen: print RecordSet         if RecordSet==False:                 return           zonedesc=RecordSet[0][0]         locationdesc = RecordSet[0][1]         messagestr="This is an automated email from your house alarm system. Alarm activated for Zone: "+zonedesc+" ("+locationdesc+")"         return messagestr  def BuildMessageFromRule(SensorNumber, smartruleid):      RecordSet = GetDataFromHost(7,[smartruleid, SensorNumber])     if RecordSet==False:         return      numrows = len(RecordSet)        messagestr="This is an automated email from PrivateEyePi. Rule triggered for Zone(s): "+RecordSet[0][3]+", Location: "+RecordSet[0][4]+" and for rule "     for i in range(0,numrows,1):         if RecordSet[i][0]==1:             messagestr=messagestr+"Alarm Activated"         if RecordSet[i][0]==2:             messagestr=messagestr+"Alarm Deactivated"         if RecordSet[i][0]==3:             messagestr=messagestr+"Circuit Open"         if RecordSet[i][0]==4:             messagestr=messagestr+"Circuit Closed"         if RecordSet[i][0]==5:             messagestr=messagestr+"Open for " + str(RecordSet[i][1]) + " Minutes"         if RecordSet[i][0]==6:             messagestr=messagestr+"Closed for " + str(RecordSet[i][1]) + " Minutes"         if RecordSet[i][0]==7:             messagestr=messagestr+"Where sensor value (" + str(RecordSet[i][5]) + ") is between " + str(RecordSet[i][1]) + " " + str(RecordSet[i][2])                     if RecordSet[i][0]==8:             messagestr=messagestr+"Tamper"         if RecordSet[i][0]==9:             messagestr=messagestr+"Day Of Week is between " + str(RecordSet[i][1]) + " and " + str(RecordSet[i][2])          if RecordSet[i][0]==10:             messagestr=messagestr+"Hour Of Day is between " + str(RecordSet[i][1]) + " and " + str(RecordSet[i][2])         if RecordSet[i][0]==11:             messagestr=messagestr+"Where secondary sensor value (" + str(RecordSet[i][6]) + ") is between " + str(RecordSet[i][1]) + " " + str(RecordSet[i][2])         if i<numrows-1:             messagestr=messagestr + " AND "         return messagestr  def SendEmailAlertFromRule(ruleid, SensorNumber, photo):         try:                 thread.start_new_thread(SendEmailAlertThread, (SensorNumber, ruleid, True, photo, ) )         except:                 print "Error: unable to start thread"  def SendEmailAlert(SensorNumber):         try:                 thread.start_new_thread(SendEmailAlertThread, (SensorNumber,0 , False, False) )         except:                 print "Error: unable to start thread"  def SendEmailAlertThread(SensorNumber, smartruleid, ruleind, photo):          # Get the email addresses that you configured on the server         RecordSet = GetDataFromHost(5,[0])         if RecordSet==False:                 return          numrows = len(RecordSet)          if globals.smtp_server=="":                 return          if ruleind:                 msgtext = BuildMessageFromRule(SensorNumber, smartruleid)         else:                 msgtext = BuildMessage(SensorNumber)          for i in range(numrows):                 # Define email addresses to use                 addr_to   = RecordSet[i][0]                 addr_from = globals.smtp_user #Or change to another valid email recognized under your account by your ISP                       # Construct email                  if (photo==1):                         files = 0                         files = glob.glob(globals.photopath)                         latestphoto = get_latest_photo(files)                         msg = MIMEMultipart()                 else:                         msg = MIMEText(msgtext)                  msg['To'] = addr_to                 msg['From'] = addr_from                 msg['Subject'] = 'Alarm Notification' #Configure to whatever subject line you want                  #attach photo                 if (photo==1):                         msg.preamble = 'Multipart message.\n'                           part = MIMEText(msgtext)                          msg.attach(part)                         part = MIMEApplication(open(latestphoto,"rb").read())                         part.add_header('Content-Disposition', 'attachment', filename=latestphoto)                         msg.attach(part)                  # Send the message via an SMTP server                  #Option 1 - No Encryption                 if globals.email_type==1:                         s = smtplib.SMTP(globals.smtp_server)                 elif globals.email_type==2:                 #Option 2 - SSL                         s = smtplib.SMTP_SSL(globals.smtp_server, 465)                 elif globals.email_type==3:                 #Option 3 - TLS                         s = smtplib.SMTP(globals.smtp_server,587)                         s.ehlo()                         s.starttls()                         s.ehlo()                 else:                         s = smtplib.SMTP(globals.smtp_server)                   s.login(globals.smtp_user,globals.smtp_pass)                 s.sendmail(addr_from, addr_to, msg.as_string())                  s.quit()                 if globals.PrintToScreen: print msg;  def SendCustomEmail(msgText, msgSubject):          # Get the email addresses that you configured on the server         RecordSet = GetDataFromHost(5,[0])         if RecordSet==False:                 return          numrows = len(RecordSet)          if globals.smtp_server=="":                 return          for i in range(numrows):                 # Define email addresses to use                 addr_to   = RecordSet[i][0]                 addr_from = globals.smtp_user #Or change to another valid email recognized under your account by your ISP                       # Construct email                 msg = MIMEText(msgText)                 msg['To'] = addr_to                 msg['From'] = addr_from                 msg['Subject'] = msgSubject #Configure to whatever subject line you want                  # Send the message via an SMTP server                 #Option 1 - No Encryption                 if globals.email_type==1:                         s = smtplib.SMTP(globals.smtp_server)                 elif globals.email_type==2:                 #Option 2 - SSL                         s = smtplib.SMTP_SSL(globals.smtp_server, 465)                 elif globals.email_type==3:                 #Option 3 - TLS                         s = smtplib.SMTP(globals.smtp_server,587)                         s.ehlo()                         s.starttls()                         s.ehlo()                 else:                         s = smtplib.SMTP(globals.smtp_server)                  s.login(globals.smtp_user,globals.smtp_pass)                 s.sendmail(addr_from, addr_to, msg.as_string())                 s.quit()                 if globals.PrintToScreen: print msg; 

回答1:

Your lcd.py module doesn't define any functions (or other top-level objects) named noDisplay or message, only a class named CharLCD and a function named DisplayLCD. So, when you try to import something that doesn't exist, of course you get an ImportError.

It's true that the CharLCD class has methods named noDisplay and message, but that doesn't mean you can just import them as top-level functions. (And, even if you could, you can't call them that way; you need a CharLCD object to call its methods.)

I suspect you need to read a basic tutorial on classes, like the Classes chapter in the official tutorial.

Meanwhile, I think the code you want is:

from lcd import CharLCD  # ...  char_lcd = CharLCD() char_lcd.message("test with message") time.sleep(5)  char_lcd.noDisplay() 

(Also note the () in the last line. You need those parentheses to call a function or method; without them, you're just referring to the function or method itself, as a value, which has no more effect than just writing 2 on a line by itself.)



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!