跟踪python源文件的变化?

时间:2014-03-19 07:18:21

标签: python migration dynamic-typing

我正在学习python,并且遇到了我需要改变函数的behvaviour的情况。我最初是一个java程序员,所以在Java世界中,函数的改变会让Eclipse显示Java中的很多源文件都有错误。这样我就可以知道哪些文件需要修改。但考虑到没有类型,人们如何在python中做这样的事情?!我使用TextMate2进行python编码。

目前我正在以蛮力的方式行事。打开每个python脚本文件并检查我在哪里使用该功能然后修改。但我确定这不是处理大型项目的方法!!!

编辑:作为示例我在python脚本文件中定义了一个名为Graph的类。 Graph有两个对象变量。我在许多脚本文件中创建了这个类的许多对象(每个都有不同的名称!)然后决定我想要更改对象变量的名称!现在我要浏览每个文件并再次读取我的代码,以便再次更改名称:(。请帮忙!

示例:文件A包含类x,y,z的对象C。文件B包含类xx,yy,zz的对象C。类C有两个实例变量名称,应更改为FooPooFoo1Poo1。还要考虑许多文件,例如AB。你会怎么做才能解决这个问题?你是不是要打开每个文件并搜索x,y,z,xx,yy,zz然后单独更改名称?!!!

5 个答案:

答案 0 :(得分:1)

哇,慢下来。您描述的编码过程不可扩展。 你究竟是如何改变这个功能的行为的?请详细说明。

更新:这听起来好像你正试图通过拼凑各种函数和局部变量来实现一个类及其方法 - 就像我第一次在Python中学习OO编码时错误地做的那样。代码气味是当某些类的内部类型/类发生变化时,它通常不会影响类方法。如果你每10分钟重构一下你的所有代码,你就会做一些严重错误的事情。退一步考虑清理分解为对象,方法和数据成员。

(如果您想要更有用的答案,请提供更多细节。)

如果你给我们详细说明,我们可以更好地批评它。

答案 1 :(得分:1)

听起来你只能在IDE中编码!

从IDE中解脱出来并成为更好的程序员的两个步骤。

  1. 为您的代码编写单元测试。

  2. 了解如何使用grep

  3. 单元测试将运用您的代码并确保它始终按照您的意愿执行操作。它们使重构变得更容易。

    grep,一个很棒的工具grep -R 'my_function_name' src将在目录src下的文件中找到对函数的每个引用。

    另外,请看这篇相当精彩的博文:Unix as an IDE

答案 2 :(得分:0)

您不会在文本编辑器中获得此功能。我使用sublime text 3,我喜欢它,但它没有这个功能。但它通过“Goto Anything”(Ctrl + P)功能跳转到文件和函数,其多重选择/多重编辑非常适合小型重构任务。

然而,当谈到IDE时,JetBrains pycharm拥有一些你可能正在寻找的令人惊奇的重新分解工具。

免费的Python Tools for Visual Studio(请参阅免费的install选项,可以使用免费的VS shell)具有一些出色的Refactoring功能和一流的REPL来启动。

我使用这三个。我把大部分时间花在了崇高的文本上,我喜欢pycharm进行重构,而且我发现PT4VS非常适合于非常复杂的原型设计。

尽管python是一种动态类型语言,IDE仍然可以在合理的程度上进行内省。但是,当然,它不会接近Java或C#IDE的级别。顺便说一下,如果你是从Java过来的,你可能会遇到JetBrains IntelliJ,PyCharm会觉得它几乎完全相同。

一个人的编程风格在像C#这样的静态类型语言和像python这样的动态语言之间肯定是不同的。我发现自己在较小的,可测试的模块中做事。迭代速度更快。在动态语言中,人们更少依赖IDE工具,而更多地依赖于涵盖关键功能的单元测试。如果您没有这些,在重构时破坏。

答案 3 :(得分:0)

静态和动态类型语言之间的权衡之一是后者在类型声明的形式中需要较少的脚手架,但在重构工具和编译时错误检测方面提供的帮助较少。一些Python IDE确实提供了一定级别的类型推断并有助于重构,但即便是最好的也无法匹配为静态类型语言开发的工具。

动态语言程序员通常会在以下一种或多种方式进行重构时确保正确性:

  1. 使用grep查找函数调用网站并修复它们。 (如果你想处理反射,你必须在像Java这样的语言中这样做。)

  2. 启动应用程序,看看出了什么问题。

  3. 编写单元测试,如果您还没有它们,请使用覆盖工具确保它们覆盖整个程序,并在每次更改后运行测试套件以检查一切是否仍然有效。

答案 4 :(得分:0)

仅针对您的修改的一个答案:

  • 如果你的旧代码工作且不需要修改,你可以将旧名称保留为新名称的别名,从而导致旧代码不被破坏。例如:

    class MyClass(object):
        def __init__(self):
            self.t = time.time()
        # creating new names
        def new_foo(self, arg):
            return 'new_foo', arg
        def new_bar(self, arg):
            return 'new_bar', arg
        # now creating functions aliases
        foo = new_foo
        bar = new_bar
    
  • 如果您的代码需要返工,请重写您的公共代码,执行所有操作,并纠正任何失败。您还可以查找您班级的任何导入/实例化。