Python 从其他两个文件生成混合*.py文件

Python 从其他两个文件生成混合*.py文件,python,parsing,Python,Parsing,我正在尝试编写一个python脚本,它可以将两个python文件组合成一个混合体,使用第二个文件中的方法覆盖第一个文件中的方法(这些方法可以是独立的,也可以存在于类中) 例如,假设我有original.py: from someclass import Class0 def fun1(a, b): print "fun1", a, b def fun2(a): print "fun2", a class Class1(Class0): def __init__(se

我正在尝试编写一个python脚本,它可以将两个python文件组合成一个混合体,使用第二个文件中的方法覆盖第一个文件中的方法(这些方法可以是独立的,也可以存在于类中)

例如,假设我有original.py:

from someclass import Class0

def fun1(a, b):
    print "fun1", a, b

def fun2(a):
    print "fun2", a

class Class1(Class0):
    def __init__(self, a):
        print "init", a

    def fun3(self, a, b):
        print "fun3", a, b
和new.py:

def fun2(a, b):
    print "new fun2", a, b

class Class1(Class0):
    def fun3(self, a, b):
        print "new fun3"
运行combine('original.py','new.py')后,我希望它生成一个新文件,如下所示:

import someclass

def fun1(a, b):
    print "fun1", a, b

def fun2(a, b):
    print "new fun2", a, b

class Class1:
    def __init__(self, a):
        print "init", a

    def fun3(self, a, b):
        print "new fun3"

我想找出最干净的方法。起初我想使用正则表达式,但跟踪缩进和我所处的当前级别(类中的方法可能有一个级别深,但如果文件在类中有类,或者在其他方法中有方法,就像使用decorator时一样),听起来像是一场灾难正在等待发生。我还考虑使用tokenize模块生成一个语法树,然后尝试导航到两个树中的同一元素,用另一个树的一部分替换一个树的一部分(同样,这似乎会变得复杂,因为我看到的tokenize的所有用法都是用于修改单个python标记,而不是整个方法)。你们有什么建议?这似乎是一项简单的任务,但我看不到一个干净的方法来完成它

另外,我不关心第二个文件是否完整或有效(注意,尽管继承自Class0,但缺少导入),尽管如果使第二个文件有效,则允许我使用一些内部python技巧(比如修改python导入逻辑,使用不同文件中的方法覆盖导入的方法,然后将导入的版本从内存转储到新文件中),我也可以这样做。

EDIT(关于我为什么尝试这样做而不是使用继承的更多解释):

我想我的问题需要更好地解释我为什么要这么做。我有几个小组/客户我正在提供我的源代码。功能需要根据客户的要求而有所不同(在某些情况下,就像sarnold提到的调整参数文件一样简单;在另一些情况下,用户要求的功能/挂钩与其他组无关,只会给UI带来更多混乱)。此外,一些源代码是特定于客户和/或专有的(因此,虽然我可以与某些组共享,但我不允许与其他组共享),这就是我试图避免继承的原因。我想我仍然可以依赖正常继承,只要它是专有的子类版本,而不是原始版本,但对于大多数功能,目前只有一个组没有特权(每个功能的组并不总是相同的)其他组也一样。因此,如果我要使用继承,我可能需要一堆目录/文件,比如“SecretFromA”、“SecretFromB”、“SecretFromZ”,然后对于其他组,我需要“from SecretFromZ import*”对于每个模块,使用我描述的替换技术,我可以只为我想要过滤的功能添加存根。这也是我将来会经常使用的东西,因此,尽管现在编写这个脚本会很痛苦,但我觉得如果不必维护过多的“from*import*,我将来会节省更多键入继承将强制我执行的文件(更不用说在客户决定移动特性时,以后必须区分每个版本)


另外,作为对sarnold评论的回应,我想我的描述太模糊了。这不是即时发生的事情。我会生成一次新的*.py文件(每个版本/交付),并将生成的源代码提供给客户。此外,修补只会在第二个文件(在我的示例中为new.py)时发生实际上存在,否则将复制原始目录。因此,与继承不同,我的组特定目录相对较小,最终版本部署到一个单独的目录中,除了将其交付给客户之外,我根本不需要维护该目录。

通过您新改进的描述,我可以提出一个解决方案我在过去以及其他团队中使用的解决方案非常有效:使用源代码管理通过分支或新存储库来管理差异

首先,请使用某种类型的系统。更高级的系统,如、、、等,都支持某种形式的合并跟踪,可以使这个特定问题更容易解决。(无论您是否决定以这种方式使用分支,请使用源代码管理系统。)

您将维护一个主分支(如果您愿意,可以称之为主干或主分支)几乎所有的开发工作、bug修复等都需要进行。从这一点出发,将特定于给定客户的所有代码进行分支。您可能更喜欢根据功能而不是客户名称进行分支,因为您可能有10个客户需要SCTP支持,而其他20个客户则需要TCP支持。(而且您希望对更奇特的协议收取更高的费用——因此,将所有协议合并到一个配置选项中对业务不利。)

在交付新产品时,您可以将分支(或存储库)更改为专门的分支、
git pull
(不同的存储库)或
git merge
(不同的分支),或
svn merge
或类似命令,将更新从主开发主干拉入专用分支。根据您是否处理了冲突的代码,您可能需要修复一些合并冲突,或者可能会非常干净。修复所有合并冲突,提交到分支,然后转到下一个分支

你很可能会得到一棵“树”,看起来像这样:

             I--J--K      supremely magic feature
            /     /
     D--E--F--L--M--N     magic feature
    /        /     /
A--B--C--G--H--O--P--Q    main trunk
获得太多的分支是一条通往疯狂的捷径;如果可以,请确保将错误修复和共享功能提交到主干中,如果不能,请尽可能靠近主干。这将使mergin