4

我正在使用 python + splinter 进行浏览器自动化。我的结构是这样的

[root]
+--start.py
+--end.py
+--[module1]
|  +--mod11area1.py
|  +--mod12area2.py
|  +--[module1_2]
|  |  +--mod121area1.py
|  +--[module1_3]
|     +--mod131area1.py
+--[module2]
   +--mod21area1.py

start.py 设置浏览器的初始化和打开,内部 modules.py 对每个模块执行操作,然后在执行时通过附加以下内容将这个结构合并到一个脚本中:

start.py
mod11area1.py
mod12area2.py
mod121area1.py
mod131area1.py
mod21area1.py
end.py

我的问题是,有没有更好的方法来做到这一点? 我对此很陌生,通常只创建一个脚本。由于我的项目不断扩大,我不得不聘请其他几个人与我一起编写脚本。因此,我想出了这种方法。

4

3 回答 3

6

不,Python 没有简单的方法将脚本合并到一个.py文件中。

但是你可以伪造它,尽管方式相当有限。


下面是一个示例,说明如何在单个文件中定义多个模块(每个模块都有自己的命名空间)。

但有以下限制。

  • 没有包支持
    (尽管这可以工作)。
  • 不支持相互依赖
    的模块(除非已经定义,否则无法导入模块)。

示例 - 2 个模块,每个模块包含一个功能:

# Fake multiple modules in a single file.
import sys
_globals_init = None  # include ourself in namespace
_globals_init = set(globals().keys())

# ------------------------
# ---- begin
__name__ = "test_module_1"
__doc__ = "hello world"

def test2():
    print(123)


sys.modules[__name__] = type(sys)(__name__, __doc__)
sys.modules[__name__].__dict__.update(globals())
[globals().__delitem__(k) for k in list(globals().keys()) if k not in _globals_init]
# ---- end ------------


# ---------------------
# ---- begin
__name__ = "some_other"
__doc__ = "testing 123"

def test1():
    print(321)


sys.modules[__name__] = type(sys)(__name__, __doc__)
sys.modules[__name__].__dict__.update(globals())
[globals().__delitem__(k) for k in list(globals().keys()) if k not in _globals_init]
# ---- end ------------


# ----------------
# ---- example use

import test_module_1
test_module_1.test2()

import some_other
some_other.test1()

# this will fail (as it should)
test1()

请注意,这不是一个好习惯,如果您遇到此问题,最好使用一些替代解决方案(例如使用https://docs.python.org/3/library/zipimport.html

于 2013-09-08T01:44:17.320 回答
1

请参阅我的GitHub 项目

可能有更好的方法可以满足您的需求。我为编程竞赛开发了这个项目/hack ,它只允许参赛者提交一个.py文件。这允许开发一个包含多个.py文件的项目,然后.py在最后将它们组合成一个文件。

@modulize我的 hack 是将函数转换为模块的装饰器。然后可以照常导入此模块。这是一个例子。

@modulize('my_module')
def my_dummy_function(__name__):  # the function takes one parameter __name__
    # put module code here
    def my_function(s): 
        print(s, 'bar')

    # the function must return locals()
    return locals()

# import the module as usual
from my_module import my_function
my_function('foo') # foo bar

我还有一个脚本,它可以将多个.py文件的项目组合在一起,这些文件相互导入到一个“.py”文件中。

例如,假设我有以下目录结构和文件:

my_dir/
    __main__.py

        import foo.bar
        fb = foo.bar.bar_func(foo.foo_var)
        print(fb) # foo bar

    foo/
        __init__.py

            foo_var = 'foo'

        bar.py

            def bar_func(x):
                return x + ' bar'

合并后的文件如下所示。顶部的代码定义了@modulize装饰器。

import sys
from types import ModuleType

class MockModule(ModuleType):
    def __init__(self, module_name, module_doc=None):
        ModuleType.__init__(self, module_name, module_doc)
        if '.' in module_name:
            package, module = module_name.rsplit('.', 1)
            get_mock_module(package).__path__ = []
            setattr(get_mock_module(package), module, self)

    def _initialize_(self, module_code):
        self.__dict__.update(module_code(self.__name__))
        self.__doc__ = module_code.__doc__

def get_mock_module(module_name):
    if module_name not in sys.modules:
        sys.modules[module_name] = MockModule(module_name)
    return sys.modules[module_name]

def modulize(module_name, dependencies=[]):
    for d in dependencies: get_mock_module(d)
    return get_mock_module(module_name)._initialize_

##===========================================================================##

@modulize('foo')
def _foo(__name__):
    ##----- Begin foo/__init__.py ------------------------------------------------##
    foo_var = 'foo'
    ##----- End foo/__init__.py --------------------------------------------------##
    return locals()

@modulize('foo.bar')
def _bar(__name__):
    ##----- Begin foo/bar.py -----------------------------------------------------##
    def bar_func(x):
        return x + ' bar'
    ##----- End foo/bar.py -------------------------------------------------------##
    return locals()

def __main__():
    ##----- Begin __main__.py ----------------------------------------------------##
    import foo.bar
    fb = foo.bar.bar_func(foo.foo_var)
    print(fb) # foo bar
    ##----- End __main__.py ------------------------------------------------------##

__main__()
于 2017-07-31T16:36:57.157 回答
-3

与其将内容附加到单个 *.py 文件中,不如直接从团队中其他人编写的代码中导入您需要的内容?

于 2013-09-07T23:55:55.053 回答