我知道这已被问到,但每次这个例子都不同于我想做的事情或者比我想做的更复杂。所以这里就是这样。
First.py
value = 10 #This variable should go to the Second script
Second.py
newdata = value #This variable should come from the First script, 10
所以我想做的就是将一个SINGLE变量传递给另一个独立运行的python。我不想将所有变量从First脚本传递到下一个脚本或调用整个第二个脚本,因为我已经看到了一些示例。我在Raspberry Pi上运行这两个脚本,第一个脚本正在读取一些传感器数据,而第二个脚本获取该数据并进一步计算它。从第一个脚本中使用了很多变量,所以我真的不想传递所有内容,只传递我想要的内容。
如果这有任何区别,我也想要v2.7。
由于
这是我的代码:{我要传递给Second.py的变量是临时}
First.py
# External module imports
import time
import os
import datetime
import MySQLdb
os.system('sudo modprobe w1-gpio')
os.system('sudo modprobe w1-therm')
# Connect to mysql
db=MySQLdb.connect("localhost","zikmir","gforce","temp_database")
cursor=db.cursor()
while True:
# Initialization
sensor= "/sys/bus/w1/devices/28-011620ee98ee/w1_slave"
# Open the file for sensor
file = open(sensor)
# Read all of the text in the file.
text = file.read()
# Close the file now that the text has been read.
file.close()
# Split the text with new lines (\n) and select the second line.
second_line = text.split("\n")[1]
# Split the line into words, referring to the spaces, and select the 10th word (counting from 0).
temp_data = second_line.split(" ")[9]
# The first two characters are "t=", so get rid of those and convert the temperature from a string to a number.
temp = float(temp_data[2:])
# Put the decimal point in the right place and display it.
temp = temp / 1000
# Display time
t= datetime.datetime.now()
print t,temp
# Push data into mySQL
sql = "INSERT INTO time_temp VALUES(now(),%s)"
cursor.execute (sql,(temp,))
db.commit()
# Wait 5 seconds
import seven_segment
seven_segment.getdata(temp)
time.sleep(5)
Second.py
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
# GPIO ports for the 7seg pins
segments = (11,2,23,8,7,10,18,25)
# 7seg_segment_pins (11,7,4,2,1,10,5,3) + 100R inline
for segment in segments:
GPIO.setup(segment, GPIO.OUT)
GPIO.output(segment, 0)
# GPIO ports for the digit 0-3 pins
digits = (22,27,17)
# 7seg_digit_pins (12,9,8) digits 0-3 respectively
for digit in digits:
GPIO.setup(digit, GPIO.OUT)
GPIO.output(digit, 1)
num = {' ':(0,0,0,0,0,0,0),
'0':(1,1,1,1,1,1,0),
'1':(0,1,1,0,0,0,0),
'2':(1,1,0,1,1,0,1),
'3':(1,1,1,1,0,0,1),
'4':(0,1,1,0,0,1,1),
'5':(1,0,1,1,0,1,1),
'6':(1,0,1,1,1,1,1),
'7':(1,1,1,0,0,0,0),
'8':(1,1,1,1,1,1,1),
'9':(1,1,1,1,0,1,1)}
try:
while True:
def getdata(temp):
n = temp
s = str(n).rjust(3)
for digit in range(3):
for loop in range(0,7):
GPIO.output(segments[loop], num[s[digit]][loop])
if (int(time.ctime()[18:19])%2 == 0) and (digit == 1):
GPIO.output(25, 1)
else:
GPIO.output(25, 0)
GPIO.output(digits[digit], 0)
time.sleep(0.001)
GPIO.output(digits[digit], 1)
finally:
GPIO.cleanup()
我有一个测试代码但由于某些原因没有在我的主代码中工作,这是我尝试过的,我成功地传递了数据:
firsttest.py
value = 1000
def main():
print("abc")
if __name__ == "__main__":
main()
secondtest.py
from firsttest import value
recieved = value
print recieved
输出确实是1000,我只需运行secondtest.py并自动执行firsttest.py。但是当我运行我的原始代码时,first.py会执行,但我没有从second.py获得任何输出 我不知道这是否与树莓有关,因为我使用了多个GPIO,或者这是编程错误。
任何帮助都会很棒。我更糟糕的解决方案是将first.py输出到一个文本文件并让second.py从那里读取它,希望它也不会相互矛盾,因为两个脚本都会同时尝试使用它?
答案 0 :(得分:3)
使用这样的导入:
file1.py:
value = 1
def main():
print("execute only if called directly")
if __name__ == "__main__":
main()
并在file2.py中:
from file1 import value
确保将两个文件放在一个包中(目录必须包含__init__.py
文件)。当然,如果文件位于另一个包中,您也可以访问该文件。
或者,您可以在file1.py中编写一个get_value()函数,该函数返回请求的值并导入此函数:
from file1 import get_value
value = get_value()
如果temp是一个经常更新的变量(因为我怀疑看你的代码),你可以做任何一个
1)编写一个函数(例如First.read_temp()
),读取温度一次,然后导入并在Second.py中使用此函数或
2)从数据库中获取temp的最新值(如果时间延迟无关紧要)。
答案 1 :(得分:2)
使用void Available_firmware_version(){
char *version = (char *) malloc(2);
strcpy(version, "");
FILE *fp;
int status = 0;
char path[PATH_MAX];
fp = popen("swift list Manto", "r");
if (fp == NULL){
printf("Error: Popen is NULL \n");
return;
}
while (fgets(path, PATH_MAX, fp) != NULL){
version = (char *) realloc(version, strlen(version) + strlen(path));
strcat(version, path);
printf("%s\n", version);
}
status = pclose(fp);
if (status == -1) {
printf("Error: Popen not closed (pclose)\n");
return;
}
free(version);
}
开始second.py
。这只会将一个名称导入您的命名空间。
请记住,必须运行整个脚本from first import value
才能使其正常运行。因此,如果您的脚本中有任何可运行的代码,请确保将其保护为类似if __name__ == '__main__'
的行。
答案 2 :(得分:1)
这会有点长,所以我写了一个介绍。
由于您试图让两个独立的进程相互通信,因此只能通过导入解决问题。一个进程必须写入数据,另一个进程必须读取它。您可以使用多种选项来执行此操作。这里有三个,但请记住还有其他方法:
subprocess
模块在它们之间进行通信。socket
模块。在上述三种方法中,第一种方法是最便携的,但你必须从另一种方法开始一个脚本。考虑到显示的代码,我无法想象这对你来说是个大问题。
第二种方法仅适用于类Unix系统,我不希望它在Raspberry Pi上出现问题。它允许您完全独立地运行进程:它们只需要在它们之间共享套接字的名称,并且您实际上可以保证使用导入它们是相同的。我不会采用这种方法,因为它可能对你的情况有点过分了。
我不知道有任何方法只使用内置模块来实现第三个选项。您可以使用像shm这样的库,但我不会详细介绍这种方法。
在我解释如何实现第1项和第2项之前,我想建议稍微重构一下代码,以简化转换过程。我希望您在getdata
中已经计划了Second.py
功能。但是,我还建议进行更多更改,以简化此过程:
<强> First.py 强>:
# External module imports import time import os import datetime import MySQLdb import seven_segment def main(): os.system('sudo modprobe w1-gpio') os.system('sudo modprobe w1-therm') # Connect to mysql db = MySQLdb.connect("localhost","zikmir","gforce","temp_database") cursor = db.cursor() # Initialization sensor = "/sys/bus/w1/devices/28-011620ee98ee/w1_slave" while True: # Open the file for sensor with open(sensor) as file: # Read all of the text in the file. text = file.read() # Split the text with new lines (\n) and select the second line. second_line = text.split("\n")[1] # Split the line into words, referring to the spaces, and select the 10th word (counting from 0). temp_data = second_line.split(" ")[9] # The first two characters are "t=", so get rid of those and convert the temperature from a string to a number. temp = float(temp_data[2:]) # Put the decimal point in the right place and display it. temp = temp / 1000 # Display time print datetime.datetime.now(), temp # Send temperature over for further processing write_out(temp) # Push data into mySQL sql = "INSERT INTO time_temp VALUES(now(),%s)" cursor.execute (sql,(temp,)) db.commit() # Wait 5 seconds seven_segment.getdata(temp) time.sleep(5) if __name__ == '__main__': main()
<强> Second.py 强>:
import RPi.GPIO as GPIO import time GPIO.setmode(GPIO.BCM) # GPIO ports for the 7seg pins segments = (11,2,23,8,7,10,18,25) # 7seg_segment_pins (11,7,4,2,1,10,5,3) + 100R inline for segment in segments: GPIO.setup(segment, GPIO.OUT) GPIO.output(segment, 0) # GPIO ports for the digit 0-3 pins digits = (22,27,17) # 7seg_digit_pins (12,9,8) digits 0-3 respectively for digit in digits: GPIO.setup(digit, GPIO.OUT) GPIO.output(digit, 1) num = { ' ': (0,0,0,0,0,0,0), '0': (1,1,1,1,1,1,0), '1': (0,1,1,0,0,0,0), '2': (1,1,0,1,1,0,1), '3': (1,1,1,1,0,0,1), '4': (0,1,1,0,0,1,1), '5': (1,0,1,1,0,1,1), '6': (1,0,1,1,1,1,1), '7': (1,1,1,0,0,0,0), '8': (1,1,1,1,1,1,1), '9': (1,1,1,1,0,1,1), } try: while True: s = str(get_temp()).rjust(3) for pos, digit in enumerate(s): for loop in range(7): GPIO.output(segments[loop], num[digit][loop]) flag = (int(time.time()) % 2 == 0) and (pos == 1) GPIO.output(25, flag) GPIO.output(digits[pos], 0) time.sleep(0.001) GPIO.output(digits[pos], 1) finally: GPIO.cleanup()
大多数更改都是清理,例如在循环外定义常量项。关键的增加是write_out
中First.py
和get_temp
中Second.py
的调用。
另请注意,First
的功能现在位于main
函数中,该函数仅在__name__ == '__main__'
时调用。这将允许您像以前一样从命令行运行First.py
作为脚本。在import First
内执行Second.py
时,它不会运行所有代码,只需定义main
之外的常量。
使用此方法,First.py
必须启动Second.py
,反之亦然。我将采用第一种方法,因为它看起来似乎有点简单。无论哪种方式,First
的标准输出都将转到Second
的标准输入。您可以将First.py
更改为如下所示:
import subprocess, sys
...
def main(proc):
...
write_out(proc, temp)
...
...
def write_out(proc, temp):
print(temp, file=proc.stdin)
proc.stdin.flush() # Necessary if you want to have real-time updates
if __name__ == '__main__':
second = subprocess.Popen([sys.executable, 'Second.py'], stdin=subprocess.PIPE, universal_newlines=True)
main(second)
在这里,首先启动Second.py
并将温度值传递给Second
的标准输入。 Here是一个相关的答案。 First.main
现在必须接受一个子流程作为参数,需要将其传递给write_out
。
Second.py
不需要任何修改:只是从stdin读取的get_temp
的定义:
def get_temp():
temp = float(sys.in.readline())
考虑到为使这项工作必须做的工作量,您可能想要完全考虑另一种方法。也许你可以定义一个在Second.py
中执行额外处理的函数(类似于我在main
中对First.py
所做的处理)。然后,每当您获得新的温度读数时,您可以在First.py
的后台线程中调用该函数。这将使您的代码更简单,更容易处理。假设您的函数名为process_temp
,您可以在First.py
中执行以下操作:
import threading
...
def write_out(temp):
thread = threading.Thread(target=Second.process_temp, args=(temp,))
thread.start()
...