Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Python中隐式地将变量传递给导入的函数?_Python_Python 3.6_Implicit - Fatal编程技术网

如何在Python中隐式地将变量传递给导入的函数?

如何在Python中隐式地将变量传递给导入的函数?,python,python-3.6,implicit,Python,Python 3.6,Implicit,模块1定义了功能1和功能2module2使用了module1中定义的两个函数,并且需要向它们传递可以描述为上下文配置参数的内容(实际上是可变自定义类的实例,而不是字符串之类的东西),每次在module2中调用这些函数时都是一样的。如果我可以避免使用普通函数参数的方式重复传递它,并且只指定一次,那么模块(module2)中调用的所有函数都可以访问它,我将不胜感激。这在Python中可能吗?我使用最新的Python 3.6module1不是第三方库,也不是已建立的代码库模块,我可以在此阶段以任何必要

模块1
定义了
功能1
功能2
module2
使用了
module1
中定义的两个函数,并且需要向它们传递可以描述为上下文配置参数的内容(实际上是可变自定义类的实例,而不是字符串之类的东西),每次在
module2
中调用这些函数时都是一样的。如果我可以避免使用普通函数参数的方式重复传递它,并且只指定一次,那么模块(
module2
)中调用的所有函数都可以访问它,我将不胜感激。这在Python中可能吗?我使用最新的Python 3.6
module1
不是第三方库,也不是已建立的代码库模块,我可以在此阶段以任何必要的方式修改定义

# --- module1.py ---

class Context:
    def __init__(self, s: str):
        self.s = s


def function1(cx: Context, s1: str):
    print(f'{cx.s} {s1}!')


# --- module2.py ---

from module1 import Context
from module1 import function1

cx = Context('Hello')

# this works and prints 'Hello World!'
function1(cx, 'World')


# this doesn't work but I want it to work and do exactly the same
# (function1 definition can be changed whatever way necessary)
function1('World')
(编辑以匹配问题中的示例代码)如果您修改函数使
cx
成为关键字参数(或者,最后一个位置参数)如下所示,则这可能是进行分部的好地方:

然后你可以做:

from module1 import Context
from module1 import function1
from functools import partial
cx = Context('hello')
function1 = partial(function1, cx = cx)
当您调用
function1
时,您将调用partial,它已经设置了
cx
参数。

(编辑以匹配问题中的示例代码)如果您修改函数使
cx
成为关键字参数(或者最后一个位置参数),这可能是一个放置partial的好地方像这样:

然后你可以做:

from module1 import Context
from module1 import function1
from functools import partial
cx = Context('hello')
function1 = partial(function1, cx = cx)
当您调用
function1
时,您将调用partial,它已经设置了
cx
参数。

您可以使用模块级全局变量执行此操作

context = None

def function1(arg1, arg2, arg3):
    # do something involving context and args
然后您只需执行从导入模块1的位置导入的
module1.context=任何内容

但更好的方法是使用一个类来保存对上下文的引用,在实例化对象时传入:

class MyFunctions(object):
    def __init__(self, context):
        self.context = context
    def function1(self, arg1, arg2. arg3):
        # do something with self.context and args
然后你就这样使用它:

 myfunctions = MyFunctions(configuration_object)
 myfunctions.function1(1, 2, 3)
通过这种方式,您可以拥有所需的任意多个上下文。

您可以使用模块级全局变量来实现这一点

context = None

def function1(arg1, arg2, arg3):
    # do something involving context and args
然后您只需执行从导入模块1的位置导入的
module1.context=任何内容

但更好的方法是使用一个类来保存对上下文的引用,在实例化对象时传入:

class MyFunctions(object):
    def __init__(self, context):
        self.context = context
    def function1(self, arg1, arg2. arg3):
        # do something with self.context and args
然后你就这样使用它:

 myfunctions = MyFunctions(configuration_object)
 myfunctions.function1(1, 2, 3)

通过这种方式,您可以拥有所需的任意多个上下文。

这是一种完全不同的方法,可能是一个糟糕、糟糕的想法,但很有趣(并且避免了
模块2
中的大部分繁琐工作):您可以制作一个装饰器,在调用方的上下文中查找
cx
,并自动将其提供给函数。像这样:

import sys
from functools import wraps

def withCallerContext(fn):
    @wraps(fn)
    def wrapped(*a, **k):
        frame = sys._getframe(0)
        while 'cx' not in frame.f_globals:
            frame = frame.f_back
            if frame is None:
                raise ValueError("must set cx in calling context")

        cx = frame.f_globals['cx']
        return fn(*a, cx = cx, **k)
    return wrapped


@withCallerContext
def function1(s1: str, cx: Context = None):
    print(f'{cx.s} {s1}!')

一种完全不同的方法,可能是一个可怕的想法,但很有趣(并且避免了
module2
中的大部分繁琐工作):您可以制作一个装饰器,在调用方的上下文中查找
cx
,并自动将其提供给函数。像这样:

import sys
from functools import wraps

def withCallerContext(fn):
    @wraps(fn)
    def wrapped(*a, **k):
        frame = sys._getframe(0)
        while 'cx' not in frame.f_globals:
            frame = frame.f_back
            if frame is None:
                raise ValueError("must set cx in calling context")

        cx = frame.f_globals['cx']
        return fn(*a, cx = cx, **k)
    return wrapped


@withCallerContext
def function1(s1: str, cx: Context = None):
    print(f'{cx.s} {s1}!')

你能展示一些代码让它更清楚你的意思吗?当然。也许你会展示一些你现在拥有的东西,并且想知道如何替换它。听起来你想要一些动态范围,Python不支持。您可能可以一起破解一些东西,但我怀疑,您应该重新设计这种方法,以使用一个类,该类将此配置对象作为参数,并在其中封装该状态,而不是依赖全局变量。@mkrieger1我已添加了代码示例。您可以展示一些代码来更清楚地说明您的意思吗?当然可以。也许你会展示一些你现在拥有的东西,并且想知道如何替换它。听起来你想要一些动态范围,Python不支持。你也许可以一起破解一些东西,但我怀疑,你应该重新设计这种方法,利用一个类,它将这个配置对象作为参数,并在那里封装那个状态,不要依赖全局变量。@mkrieger1我添加了代码示例使用类是一个明显的解决方案,但会有许多函数,它们将是长的、相互独立的,只共享一个变量(事实上,我很乐意将每个函数放在一个单独的文件中,也许我会制作一个包),该类不会表示逻辑上真实的实体,并且。。。我选择Python的一个主要原因是,我可以定义一个没有类的函数:-)它们共享状态(这一个变量),如果您不想将其传递给每个函数,那么将它们放在一个类中是完全合理的。我想要的答案是
module1.context=whatever
。我以前试过的是从module1 import*
导入
,然后是
context=which
,但没有成功。现在我
导入module1
,然后设置
module1.context=which
,然后从module1导入
,一切似乎都正常。坦克!使用类是一个明显的解决方案,但会有许多函数,它们将是长的、相互独立的,只共享一个变量(事实上,我很乐意将每个函数放在一个单独的文件中,也许我会制作一个包),类不会表示逻辑上真实的实体,并且。。。我选择Python的一个主要原因是,我可以定义一个没有类的函数:-)它们共享状态(这一个变量),如果您不想将其传递给每个函数,那么将它们放在一个类中是完全合理的。我想要的答案是
module1.context=whatever
。我以前试过的是从module1 import*
导入
,然后是
context=which
,但没有成功。现在我
导入module1
,然后设置
module1.context=which
,然后从module1导入
,一切似乎都正常。坦克!您甚至可以在模块中提供一个函数,在给定上下文选项的情况下,该函数返回所有函数的部分