Python Forum

Full Version: Can I get some clarification on importing functions from external files.
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I'm familiar with programming syntax and constructs but very new to Python. I am trying to figure out how to modularize some functions into separate files so they can be "included" in a main program script.

This is my "all in one script"

    # main.py> 
    import machine
    import time

    led = machine.Pin(13, machine.Pin.OUT)

    def blink_led_n_times(num, t_on, t_off, msg):
        
        counter = 0
        
        while (counter < num):
            led.on()
            time.sleep(t_on)
            led.off()
            time.sleep(t_off)
            counter += 1
            
        print(msg)
        
    blink_led_n_times(10,.5,.5,'Done Blinking.')
I can run this, it works as expected.

So lets say for example I want to move the function blink_led_n_times() to it's own file.

Now I have "blink.py"

    # blink.py>
    def blink_led_n_times(num, t_on, t_off, msg):
        
        counter = 0
        
        while (counter < num):
            led.on()
            time.sleep(t_on)
            led.off()
            time.sleep(t_off)
            counter += 1
            
        print(msg)
So I want to include/import that into my main program script.

    # main.py> 
    import machine
    import time
    from blink import blink_led_n_times

    led = machine.Pin(13, machine.Pin.OUT)

    blink_led_n_times(10,.05, .05, 'w00t')
When I run main.py I get this error:

Error:
Traceback (most recent call last): File "<stdin>", line 8, in <module> File "blink.py", line 7, in blink_led_n_times NameError: name 'led' isn't defined
So my first real question is: 1. Why is blink_led_n_times() unable to read/connect with the led object?

I'll modify blink_led_n_times() to accept an led_object as it's first parameter.

blink.py is now set to

    # blink.py>
    def blink_led_n_times(led_obj, num, t_on, t_off, msg):
        
        counter = 0
        
        while (counter < num):
            led_obj.on()
            time.sleep(t_on)
            led_obj.off()
            time.sleep(t_off)
            counter += 1
            
        print(msg)
and main.py is now set to

    # main.py> 
    import machine
    import time
    from blink import blink_led_n_times

    led = machine.Pin(13, machine.Pin.OUT)

    blink_led_n_times(led, 10,.05, .05, 'Done Blinking.')
So run it, and I get this error:

Error:
Traceback (most recent call last): File "<stdin>", line 8, in <module> File "blink.py", line 8, in blink_led_n_times NameError: name 'time' isn't defined
My second question: 2. Why is blink_led_n_times() unable to use time when I have clearly imported time into main.py

So I modify blink.py

    # blink.py>
    import time

    def blink_led_n_times(led_obj, num, t_on, t_off, msg):
        
        counter = 0
        
        while (counter < num):
            led_obj.on()
            time.sleep(t_on)
            led_obj.off()
            time.sleep(t_off)
            counter += 1
            
        print(msg)
And when I run it, it works correctly.

Last Questions.

-3. So if I want to import my own functions, do I have to declare all of their imports externally like I have done here with blink.py importing time?

-4. Is there a way to just "include" python code from a separate file, similar to how require or include works in PHP (that's the language I am most familiar with)

Thanks for reading! All help is greatly appreciated.
There is no led object in blink.py. there is one in main.py, but blink.py does not import main.py.

import creates a module object, a dictionary like thing that can be used to access variables objects defined in the module. Import does npt pull in the module code to be compiled with your code.

Answer 2: same answer as above.

Answer 3: when you write modules, you need to import any modules it udes. Does not matter if that module is main.py or blink.py

Answer 4: Not that I know of. Even if it were possible you would not want to do so. It creates an external dependency on the module, making any long term mantenance difficult. Any changes to the group import would require a code review of everything using the import.
Quote:import creates a module object, a dictionary like thing that can be used to access variables objects defined in the module. Import does npt pull in the module code to be compiled with your code.

Hrm OK, I'll have to think about that a little further. I am confused by this behaviour, not too sure why.

Quote:Answer 3: when you write modules, you need to import any modules it udes. Does not matter if that module is main.py or blink.py

So executing a series of scripts that import the same external module multiple times is A-OK?

Quote:Answer 4: Not that I know of. Even if it were possible you would not want to do so. It creates an external dependency on the module, making any long term mantenance difficult. Any changes to the group import would require a code review of everything using the import.

Gotcha. So when writing external functions make them as self contained as possible?
import is very different than C #include. #include pulls in code from a header file to be compiled into your module. import creates an object that is an interface to the imported module. When blink calls time.sleep(1), it does the following.

Blink says "Hey there time, can I use your sleep function?". Time says "Sure, whoever you are. Here it is. Have fun."

Importing the same module in multiple scripts is common and very efficient.

Decoupling modules is always good design. main.py should not import time. Only import wat you use directly. Blink needs time, main does not.