общей структура модуля что-то вроде:
imports ...
<constants>
options = {verbose=0, etc}
# alt options = argparse.Namespace(logging=False,....)
def levelone(args, **kwargs):
....
def leveltwo(...):
def levelthree(...):
<use constant>
<use options>
def parser():
p = argparse.ArgumentParser()
....
args = p.parse_args() # this uses sys.argv
if __name__=='__main__':
args = parser()
options.update(vars(args))
levelone(args)
Корпуса модуля имеет определение функций, и может быть импортирован другим модулем. Если используется как сценарий, то parser
читает командную строку. Этот глобальный options
доступен для всех видов state
как параметры. В смысле это константы, которые пользователь или модуль импорта могут настроить. Значения, импортированные из файла config
, могут иметь одинаковую роль.
Другой распространенный шаблон - это сделать ваши методы функций класса и передать args
в качестве атрибутов объекта.
class Foo():
def __init__(self, logging=False):
self.logging = logging
def levelone():
def leveltwo():
<use self.logging>
foo(args.logging).levelone()
Хотя globals
обескураживают, это больше, потому что они злоупотребляют, и портить модульность, что функции обеспечивают. Но Python также предоставляет пространство имен уровня module
, которое может содержать больше, чем просто функции и классы. И любая функция, определенная в модуле, может получить доступ к этому пространству имен, если только его собственные определения не теневые.
var1 = 'module level variable'
var2 = 'another'
def foo(var3):
x = var1 # read/use var1
var2 = 1 # shadow the module level definition
etc
================
Я не уверен, что я должен рекомендовать это или нет, но можно разобрать sys.argv
в third_level
.
def third_level():
import argparse
p = argparse.ArgumentParser()
p.add_argument('-v','--verbose',action='count')
args = p.parse_known_args()
verbose = args.verbose
<logging>
argparse
импорта sys
и использует sys.argv
.Он может сделать это независимо от того, используется ли он на уровне вашего скрипта, в вашем main
или вложенной функции. logging
делает такой же вещь. Вы можете использовать свой собственный импортированный модуль, чтобы скрытно передавать значения в функции. Очевидно, что можно злоупотреблять. A class
с атрибутами класса также можно использовать таким образом.
Не выполняйте регистрацию в своем 'third_level (..)'. Используйте 'if args.verbose: logging.setLevel (logging.INFO)' вместо этого. – SuperSaiyan
Я бы только передал объект 'args' первой функции. Если другим нужны значения из него, я передам их как значения в сигнатуре функции, чтобы дать понять, что им нужно. Назовите их «second_level (verbose = args.verbose)» и т. Д. – Ben