【问题标题】:Check name of running script file in module检查模块中运行脚本文件的名称
【发布时间】:2018-02-14 16:08:18
【问题描述】:

我有 2 个导入相同模块的应用程序文件:

#app1.py
import settings as s
another code

#app2.py
import settings as s
another code

我需要在模块中检查是否运行第一个或第二个应用程序:

#settings.py
#pseudocode
if running app1.py:
   print ('app1')
elif:
   print ('app2')

我检查了模块inspect,但不知道。

我也愿意接受所有更好的解决方案。

编辑:我觉得有点傻(我想这很容易)

我试试:

var = None
def foo(a):
    var = a

print (var)

但仍然是None

【问题讨论】:

  • 为什么不在模块中添加一些标志或变量来确定是app1 还是app2 调用它?
  • Settings.py 对于两个应用程序几乎相同,只有一个变量不同,但这个变量对另外 20 个变量很重要。所以为了避免重复,我希望只有一个文件。
  • @FlashTek - 你能解释更多,最好的答案吗?
  • 根据谁导入模块在模块中运行代码是代码异味...
  • @cᴏʟᴅsᴘᴇᴇᴅ - 设计应用程序对我来说是个未知数:(但如果解释更多,我会很有帮助。

标签: python module main


【解决方案1】:

正如其他人所说,也许这不是实现它的最佳方法。如果你确实想要,使用sys.argv 来识别调用模块怎么样?

应用程序:

import settings as s

设置:

import sys
import os
print sys.argv[0]
# \\path\\to\\app.py
print os.path.split(sys.argv[0])[-1]
# app.py

当然,这会为您提供最初从命令行运行的文件,因此,如果这是进一步嵌套的导入集的一部分,这将不适合您。

【讨论】:

    【解决方案2】:

    我不确定进口商是否可以知道是谁进口的。即使是这样,对我来说听起来也像是代码异味。

    相反,您可以将要采取的行动的决定委托给app1app2,而不是让settings 做出决定。

    例如:

    settings.py

    def foo(value):
        if value == 'app1': 
            # do something        
        else:
            # do something else
    

    app1.py

    from settings import foo    
    foo('app1')
    

    等等。


    在函数内赋值并让它反映在global 变量上。示例:

    A.py

    var = None
    
    def foo(a):
        global var
        var = a
    
    def print_var():
        print(var)
    

    test.py

    import A
    
    A.print_var()
    A.foo(123)
    A.print_var()
    

    输出:

    None
    123
    

    请注意,一般不建议将globals 用作编程实践,因此请尽可能少地使用它们。

    【讨论】:

    • 看起来很不错,经过测试;)
    • @jezrael 很高兴我能帮上忙 :)
    • 恐怕我没有那么具体。如果我使用你的函数,我需要在settings.py 中设置另一个变量。但我做不到。我尝试 uggly 测试 var = ''def check_run_file(a): var = a print (var) #outside def。你怎么看?
    • 我猜有问题函数在另一个app.py运行:(
    • @jezrael 您应该将所有可配置变量作为参数传递给正在导入它的脚本foo。所以我会说这是唯一的方法。你最初可以做var=None。它不那么难看。
    【解决方案3】:

    我认为您当前的方法不是解决问题的最佳方法。你也可以通过稍微修改settings.py 来解决这个问题。你有两种可能的方法:要么使用coldspeed的解决方案,要么使用代表。无论哪种方式,您都必须将模块的代码存储在函数中。

    解决此问题的另一种方法是(取决于取决于应用名称的代码行数)将函数/委托作为参数传递给函数,如下所示:

    #settings.py
    def theFunction(otherParemters, callback):
        #do something
        callback()
    
    #app1.py
    from settings import theFunction
    def clb():
        print("called from settings.py")
        #do something app specific here
    
    theFunction(otherParameter, clb)
    

    inspect 解决方案相比,这似乎是一种更简洁的解决方案,因为它可以更好地分离两个模块。

    很大程度上取决于应用的范围,是选择第一版还是第二版;或许您可以向我们提供有关您尝试解决的更广泛问题的更多信息。

    【讨论】:

    • 这与我的答案相同,但有更多的绒毛。希望更改您的答案或删除。谢谢。
    • 你可以保留你的第二个解决方案,它似乎是第一个解决方案的派生,但完全不同,我可以放手。谢谢!
    • @cᴏʟᴅsᴘᴇᴇᴅ 可以吗?
    【解决方案4】:

    这对我有用。

    import inspect
    import os
    
    curframe = inspect.currentframe()
    calframe = inspect.getouterframes(curframe, 1)
    
    if os.path.basename(calframe[1][1]) == 'app1.py':
       print ('app1')
    else:
       print ('app2')
    

    【讨论】:

    • 我得到<frozen importlib._bootstrap>作为python3.4的输出。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-21
    相关资源
    最近更新 更多