简体   繁体   English

Python通过多个其他模块重用同一模块

[英]Python reuse the same module by multiple other modules

Is it possible to achieve this in python? 有可能在python中实现吗? Basically, shared_fun() is a very frequently used utility function, used in multiple modules (user_module1 and user_module2). 基本上,shared_fun()是一个非常常用的实用程序函数,用于多个模块(user_module1和user_module2)。 However, each user wants a slightly different parameter SHARE_GLOBAL_VAR. 但是,每个用户都想要一个略有不同的参数SHARE_GLOBAL_VAR。

Some motivation why I would want it this way: 我为什么要这样的一些动机:

A. Imagine there are a lot of shared_fun(), shared_fun1(), shared_fun2() ...... and all of them rely on the same SHARE_GLOBAL_VAR but do different things with it. 答:想象一下,有很多shared_fun(),shared_fun1(),shared_fun2()……并且它们都依赖于相同的SHARE_GLOBAL_VAR,但它们执行的操作不同。 Therefore I really don't want to make SHARE_GLOBAL_VAR an argument for every one of those shared_fun(SHARE_GLOBAL_VAR) 因此,我真的不想让SHARE_GLOBAL_VAR成为每个shared_fun(SHARE_GLOBAL_VAR)的参数。

B. I want to make the maintenance of shared_fun() easy so that I don't want to copy the code into each user_module.py file individually. B.我想使shared_fun()的维护变得容易,所以我不想将代码分别复制到每个user_module.py文件中。

I think the task boils down to make a copy of share module namespace inside each user_module namespace, which I'm not sure if it's legal in python. 我认为任务归结为在每个user_module命名空间中制作一个共享模块命名空间的副本,我不确定在python中是否合法。

#share.py:
SHARE_GLOBAL_VAR = 0
def shared_fun():
    return SHARE_GLOBAL_VAR

#user_module1.py:
import share
share.SHARE_GLOBAL_VAR = 1
def user1_fun():
    return share.shared_fun()

#user_module2.py:
import share
share.SHARE_GLOBAL_VAR = 2
def user2_fun():
    return share.shared_fun()

#main.py:
import user_module1
import user_module2
# expecting a result of 1
print(user_module1.user1_fun())
# expecting a result of 2
print(user_module2.user2_fun())

You can make use of the concept of closure , for example 例如,您可以利用闭包的概念

def sharedFun():
    shared_var=0
    def getSharedVariable(shared_value=None):
        if shared_value:
            return shared_value
        else:
            return shared_var
    return getSharedVariable


shared=sharedFun()
print shared(1) # output 1
print shared(2) # output 2
print shared(3) # output 3
print shared() # output 0

you can find more about closure here 你可以在这里找到更多关于封闭的信息

For a given file on disk, there is at most one in-memory module object per process, so what you show above, with multiple imports in one process, will not work. 对于磁盘上的给定文件,每个进程最多有一个内存模块对象,因此,上面显示的在一个进程中具有多个导入的内容将不起作用。 This is why it is 'impolite' for 3rd party library modules to 'monkey patch' standard library modules and why global data variables are generally discouraged. 这就是为什么第三方库模块“猴子补丁”标准库模块是“不礼貌”的原因,并且通常不建议使用全局数据变量。

pushpendra's answer of closure is fantastic!!! pushpendra关闭的答案太棒了!!! I know very little about functional programming but this is really inspiring me to dig more into it. 我对函数式编程知之甚少,但这确实鼓舞了我进一步深入研究它。

On the other hand, I just came up with an OOP solution for my specific issue: make the shared.py a class and all the shared_fun as class method while SHARE_GLOBAL_VAR is now a class data member. 另一方面,我只是针对我的特定问题提出了OOP解决方案:将shared.py用作类,并将所有shared_fun用作类方法,而SHARE_GLOBAL_VAR现在是类数据成员。 Each user_module1/2 will now just instantiate an object of the share class with different SHARE_GLOBAL_VAR. 现在,每个user_module1 / 2都将使用不同的SHARE_GLOBAL_VAR实例化共享类的对象。

This achieves the similar idea of creating multiple copies of share_fun, via a class instead of duplicating module importing (which is impossible per Terry's answer ). 这实现了类似的想法,即通过类而不是复制模块导入来创建share_fun的多个副本(根据Terry的回答是不可能 )。

My very naive comparison between OOP and Functional in this case: Closure solution provides much more freedom in creating different versions of functions. 在这种情况下,我对OOP和Functional的比较天真的比较:Closure解决方案为创建不同版本的Function提供了更多的自由。 Since closure provides function duplicate per function instead of per GLOBAL_SHARE_VAR, therefore it saves the overhead of creating unnecessary methods that are never used by the OOP solution. 由于闭包为每个函数(而不是每个GLOBAL_SHARE_VAR)提供函数副本,因此它节省了创建不必要的方法的开销,而这些不必要的方法是OOP解决方案从未使用过的。

Time to get serious about functional programming! 是时候认真对待函数式编程了!

Claim down guy. 要求下来的家伙。 Let me explain step by step for you. 让我逐步为您解释。

First, take a careful look at your accepted answer. 首先,仔细查看您接受的答案。 Actually, there is no essential difference between this answer and a modified version of your original question. 实际上,此答案与原始问题的修改版本之间没有本质区别。

#share.py:
SHARE_GLOBAL_VAR = 0
def getSharedVariable(shared_value=None):
    if shared_value:
        return shared_value
    else:
        return SHARE_GLOBAL_VAR

In accepted answer, the scope is function sharedFun while the scope is module in the above snippet. 在公认的答案中,作用域为函数sharedFun而作用域为上述代码段中的模块。 There are almost the same. 几乎一样。 You can use the above snippet like this: 您可以这样使用上面的代码段:

import share
shared = share.getSharedVariable
print shared(1) # output 1
print shared(2) # output 2
print shared(3) # output 3
print shared() # output 0

You are still passing an identical value to getSharedVariable . 您仍将相同的值传递给getSharedVariable

Further, let's talk about your OOP solution. 此外,让我们谈谈您的OOP解决方案。 It is just meaningless. 这只是没有意义的。 If each object will have their own different SHARE_GLOBAL_VAR , why this variable called SHARE_GLOBAL_VAR ? 如果每个对象都有各自不同的SHARE_GLOBAL_VAR ,为什么将此变量称为SHARE_GLOBAL_VAR It is just a normal local variable. 它只是一个普通的局部变量。

Finally, let's modify the accepted answer: 最后,让我们修改接受的答案:

# assume SHARE_GLOBAL_VAR equals to 0.
def getSharedVariable(shared_value=SHARE_GLOBAL_VAR):
    return shared_value

shared = getSharedVariable
print shared(1) # output 1
print shared(2) # output 2
print shared(3) # output 3
print shared() # output 0

Do you notice what you are actually want? 您注意到您实际上想要什么吗? Just a default parameter. 只是一个默认参数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM