importing custom python modules.. why do only some

2019-08-21 09:05发布

问题:

I need to create a python module that many scripts need to ultimately import from:

  • Custom arg parsing to set format and constant args (i.e. my verbose and help args, and everything visually pleasing/consistent across scripts)

My custom module is currently working independently and I'm satisfied enough to move forward for now, but I can't seem to import it into another script properly. THAT module imports another module (ver.py) defining a simple variable constant with no issues (a version code I want to exist in only one location). But when I try to import that file into another (e.g. myexecutable.py) and add code for parsing additional arguments, it fails. Also, I have _ _init__.py in the dir which contains all of the files I'm working with right now.

This code has changed so much and I can't get it back to a "partially working" state, but I can get it to have no errors. Here's what's not throwing errors:

#!/usr/bin/env python
import argparse
import par as pp  ##par.py is my working parsing code

pp.preq.add_argument('input', metavar=" INPUT.ext", type=argparse.FileType('rt'))
pp.preq.add_argument('output', metavar=" OUTPUT.ext", type=argparse.FileType('wt'))

Of note, I am hoping to define the 'description' and 'usage' in the executed file, not the imported file. Here's a subset of what the imported file (par.py) has:

class USAGEformat(argparse.RawTextHelpFormatter):
        def add_usage(self, usage, actions, groups, prefix=None):
                if prefix is None:
                        prefix = 'nameconstant '+v.VERSION+'\n\nUSAGE:  '+prog
                super(USAGEformat, self).add_usage(usage, actions, groups, prefix)

parse = argparse.ArgumentParser(add_help=False, formatter_class=USAGEformat)

preq = parse.add_argument_group("___________________\n++ COMPULSORY ARGS")

When I try to add in anything more with ArgumentParser, it doesn't recognize my USAGEformat class. At some point I got my script to recognize it partially, and take my defined usage but not my defined description or compulsory arguments. Can't figure out what I did though..

Why are my variables only working when importing when they are simple:

VERSION = "v1.0"

but not when they are more complex, and why are my classes not carrying over either? I'm assuming I'm missing some basic understanding of how this works and failing to figure out what that is? I've been teaching this language to myself with tutorials/Google because I'm not a computer scientist, and some direction would be greatly appreciated.

回答1:

Your previous question and code:

Fully customized Python Help Usage

With import par as pp, the all variables, classes and functions defined in that module have to be accessed with the pp. prefix. Thus pp.parser is the parser object that was created on import. pp.preq is one of the argument groups.

pp.USAGEformat is the custom formatter class. But a formatter, an object of this class is not created when the parser is created nor when par is imported. A formatter is created from the specified class when you ask for help or usage ('-h', pp.parser.print_help()).

(edit) This was wrong:

This formatter will take globals variables like version and prog from the current namespace (the importing one), not the pp one.

The formatter still takes version from the imported namespace. But I can change that with:

pp.version = '3.0'

(see my edit in https://stackoverflow.com/a/47118317/901925)

You can test this behavior in pre itself by changing version at the end of the file and doing a new print_help(). You'll see a change in the display.

pp.parser on the other hand is created on import. You could modify pp.parser.description, the attribute that was set on creation. Setting or changing pp.description doesn't do it.

When you do parser.print_help(), it calls parser.format_help, which in turn calls parser._get_formatter. That method uses parser.formatter_class to create a formatter object, which is then 'filled' and 'executed'. There's a lot of flexibility in this approach, but it can be confusing.