Python:如何跨模块使用变量

use*_*667 6 python module global-variables raspberry-pi

我正在试图弄清楚如何在模块中使用变量和设置.

当我认为将程序的单独功能保存在单独的模块中时,我是否正确?

我有一个主程序模块main.py,在其中我有这个:

# Sets GPIO's to HIGH = Relays OFF
try:
    import RPi.GPIO as GPIO
except RuntimeError:
    Print("Error importing RPi.GPIO!!")

GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)
# GPIO16 is relay1
GPIO.setup(16, GPIO.OUT, initial=GPIO.HIGH)
# GPIO11 is relay2
GPIO.setup(11, GPIO.OUT, initial=GPIO.HIGH)
Run Code Online (Sandbox Code Playgroud)

然后我import是一个模块(在该模块中我有一个函数调用Relay)并尝试使用该函数module1.Relay(1,1)

但是函数module1需要GPIO从main.py到Work.我该如何解决这个问题?我真的不想要GPIO设置部分module1,我不希望每次运行module1.Relay(1,1)调用时都运行它.

跨模块工作的最佳实践是什么?(我正在为我家的供暖系统制作一个控制器.)

Luk*_*raf 3

您将应用程序的单独功能保留在不同的模块中是正确的 - 将代码分组在逻辑相关的单元中绝对有意义。但这并不总是微不足道的,并且迫使您清楚地思考这取决于什么以及关注点的分离。您在这里遇到的称为循环导入

有两种明显的方法可以解决循环导入:

  • 提取多个模块共享的内容,并将其放入单独的模块中。在你的情况下,这GPIO包括它的初始化。
  • 不要导入每个模块中共享的东西,而是导入一次并将其作为参数传递其他需要它的东西。

将其提取到自己的模块中

将初始化提取GPIO到它自己的模块中可能如下所示:

主要.py

from gpio import GPIO
import module1

print "main: %s" % GPIO.__name__
# Do stuff wth GPIO

module1.Relay()
Run Code Online (Sandbox Code Playgroud)

GPIO.py

# Sets GPIO's to HIGH = Relays OFF
try:
    import RPi.GPIO as GPIO
except RuntimeError:
    print("Error importing RPi.GPIO!!")

print "Setting up GPIO"
GPIO.state = 'initialized'
print "Done setting up"
Run Code Online (Sandbox Code Playgroud)

模块1.py

from gpio import GPIO

def Relay():
    print "Relay: %s" % GPIO.__name__
    # Do stuff with GPIO
Run Code Online (Sandbox Code Playgroud)

运行时输出main.py

Setting up GPIO
Done setting up
main: RPi.GPIO
Relay: RPi.GPIO
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,模块全局范围内的 GPIO 初始化gpio.py仅运行一次,即第一次将模块导入到任何地方时。

作为参数传递

另一种选择是导入 GPIO 一次并作为参数传递,如下所示:

主要.py

# Sets GPIO's to HIGH = Relays OFF
try:
    import RPi.GPIO as GPIO
except RuntimeError:
    print("Error importing RPi.GPIO!!")

print "Setting up GPIO"
GPIO.state = 'initialized'
print "Done setting up"

import module1

print "main: %s" % GPIO.__name__
# Do stuff wth GPIO

module1.Relay(GPIO)
Run Code Online (Sandbox Code Playgroud)

模块1.py

def Relay(gpio):
    print "Relay: %s" % gpio.__name__
    # Do stuff with GPIO
Run Code Online (Sandbox Code Playgroud)

在我看来,对于你的情况来说,这两种方法都是有效的。我个人更喜欢在中央模块中进行初始化gpio.py,然后从那里导入,但这只是一个品味问题。