You are right in that you support the separate functionality of your application in different modules - it is perfectly reasonable to group your code in logically related units. This is not always trivial, and it makes you think clearly about it, which depends on what the separation of problems is. What you met here is called circular import .
There are two obvious ways to resolve cyclic import operations:
- Remove the item used by several modules and place it in a separate module. In your case,
GPIO including its initialization. - Do not import the item that is used in each module, and then import it once and pass it as an argument to the other things that it needs.
Extract it to your own module
Extracting GPIO initialization into its own module might look like this:
main.py
from gpio import GPIO import module1 print "main: %s" % GPIO.__name__
gpio.py
# Sets GPIO 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"
module1.py
from gpio import GPIO def Relay(): print "Relay: %s" % GPIO.__name__
Output when starting main.py :
Setting up GPIO Done setting up main: RPi.GPIO Relay: RPi.GPIO
As you can see, GPIO initialization in the global area of the gpio.py module gpio.py launched only once, the first time the module is imported anywhere.
Pass as an argument
Another option, importing the GPIO once and passing it as an argument, might look like this:
main.py
# Sets GPIO 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__
module1.py
def Relay(gpio): print "Relay: %s" % gpio.__name__
Both are valid ways in your case, in my opinion. I personally would prefer initialization in the central gpio.py module and then import from there, but this is just a matter of taste.