Python Forum

Full Version: Modules and namespaces (again?)
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Perhaps all I need is someone who can describe how to do this. I am writing a program which is getting lengthy, and wanted to move some subroutines to a separate 'module.' I realize Python modules are a good bit more than C 'include' files but I guess I missed something.

(note that I cut down the program to show just what I *think* is germane):

The mainline "forum_ask.py" (I couldn't get the code label to work)
import requests
import binascii
import json
import ipaddress
import struct
import argparse
import re
import urllib3
import socket
import invmsites_subs
from datetime import datetime
from forum_ask_subs import get_excl_ips
from forum_ask_subs import get_incl_ips


logfile = "invmsites.log"
sites_dict = {}          # <-- This will be an issue too


def log_rtn(message):
    # Module to handle logging program actions

    whenlog = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    log = open(logfile, 'a')
    log.write(whenlog + " " + message + "\n")
    log.close()


def get_args():
    # simplified, but normally works
    log_rtn("after parse_args")

    return 'makesites'

def makesites():

    sites_list = get_sites_list()

    site_incl = build_sites_dict()
    if site_incl:
        return True

def get_sites_list():
    log_rtn("Starting get_sites_list")
    result_list = ["None"]
    # does stuff here to make a list
    return result_list

def build_sites_dict():
    """build_sites_dict will include 4 routines, to add included IPs,
    excluded IPs, included asset groups and excluded asset groups. Each of the
    four will be lists, nested within the value of the sites_dict entries"""
    log_rtn("Starting build_sites_dict")

    result_ipincl = get_incl_ips()
    if not result_ipincl:
        log_rtn("get_incl_ips failed")
        return False
    else:
        return True


if __name__ == "__main__":
    log_rtn("Starting main")
    run_params = vars(get_args())  # get args
    # logic here to control runtype
    if (run_params == "makesites"):
        log_rtn("Going to makesites.")
        result_ok = makesites()
        if result_ok:
            print("makesites worked.\n")
        else:
            print("makesites not so much.\n")

    log_rtn("Done for now")
The subroutines I moved to "forum_ask_subs.py" in the same directory:
import ipaddress
import json
import re
import socket

import requests


def get_excl_ips():
    # test func for now
    log_rtn("In get_excl_ips.")
    return True


def get_incl_ips():
    log_rtn("Doing get_incl_ips")

    return True
When I run the actual program I get an error from line 2 (adjusted for this illustration) of the get_incl_ips() routine:
Error:
NameError: name 'log_rtn' is not defined
I understand that modules are separate namespaces (as in 'var1' inside a function is different than the 'var1' I define outside the function), but I wasn't expecting that log_rtn() would not be available.

Would having an __init__.py in the folder, with import statements for everything, solve this?

BONUS Big Grin I suspect I'm going to run into something similar when I try to use sites_dict in one of the imported modules. THAT I can fix by passing it to the call of the subroutine, but if so would THIS be legal?
sites_dict = some_function(sites_dict)
Thanks for the help!

Triv

P.S. 6 edits later I think this is correct now.
you are calling log_rtn from the forum_ask_subs.py module, but it's defined in the first module and not visible when called from the second.

One way to solve this would be to have a logger.py module, which contains all of the logging functions, and import in both of the other modules