【问题标题】:Tracking changes in python source files?跟踪python源文件的变化?
【发布时间】:2014-03-19 07:18:21
【问题描述】:

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

目前我正在做蛮力的方式。打开每个 python 脚本文件并检查我在哪里使用该函数,然后修改。但我敢肯定这不是处理大型项目的方式!!!

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

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

【问题讨论】:

  • 您启动应用程序并查看出现了什么问题,或者您使用分析器/语法检查来为您进行检查?或者您自己跟踪您的代码,没有人比您更了解您的代码。此外,您所描述的不是 Java 或 Python 的东西,而是 IDE 的东西。它是跟踪更改并将其呈现给您的 IDE。我猜你可以通过使用 Eclipse for Python 来实现同样的目标?
  • @Torxed:这听起来像是 Java 的事情,因为方法上的 Java 多态性很糟糕:我们需要为同一个方法编写 99 个签名。而不是 Python 方式:使用默认参数定义一次方法,然后根据传递的 arg(s) 的类型/类找出正确的做法。
  • 我对您的代码示例的反应:您不应该直接从客户端代码(即文件 A、B)引用成员变量。他们应该打电话给getter/setter method on the object, or to be more Pythonic, a property。您的客户端代码永远不需要知道内部数据成员名称(没有 myobj.mymember 引用!)。 但您仍在描述问题的症状,而不是问题本身。您的客户端代码实际上试图对数据成员 Poo、Poo1 做什么
  • Graph 有两个对象变量”。这并不能告诉我们太多。但是它们是干什么用的?继任者和有效载荷?前任和后继者? ...?

标签: python migration dynamic-typing


【解决方案1】:

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

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

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

  2. 了解如何使用 grep

单元测试将锻炼您的代码,并确保它始终按照您的意愿行事。它们使重构变得更加容易。

grep,多么棒的工具grep -R 'my_function_name' src 可以在src 目录下的文件中找到对您函数的所有引用。

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

【讨论】:

  • 舌头可能会有点脸颊... :) 而且我确实使用集成开发环境。这是一个很棒的,叫做 Linux。
【解决方案2】:

哇,慢点。您描述的编码过程不可扩展。 你究竟是如何改变函数的行为的?请提供具体细节。

更新:这听起来像是您试图通过将杂乱无章的函数和局部变量拼凑在一起来实现一个类及其方法——就像我第一次在 Python 中学习 OO 编码时错误地做的那样。代码气味是当某些类内部的类型/类发生变化时,一般应该不会影响类方法。如果您每 10 分钟重构一次所有代码,那么您就做错了。退后一步,考虑清楚地分解为对象、方法和数据成员。

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

如果您给我们提供细节,我们可以更好地批评它。

【讨论】:

  • 我更新了答案,并在您的问题下方添加了更多评论/澄清请求 - 请回复。基本上你的数据成员用于是什么?从客户端代码(向我尖叫“方法”)解释您需要访问它们的目的是什么?
【解决方案3】:

您不会在文本编辑器中获得此功能。我使用sublime text 3,我喜欢它,但它没有这个功能。但是,它确实通过其“转到任何内容”(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 工具,而更多地依赖于涵盖关键功能的单元测试。如果你没有这些,你在你重构时破坏事情。

【讨论】:

    【解决方案4】:

    仅针对您的编辑的一个答案:

    • 如果您的旧代码可以正常工作并且不需要修改,您可以保留旧名称作为新名称的别名,这样您的旧代码就不会被破坏。示例:

      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
      
    • 如果您的代码需要返工,请重写您的通用代码,执行所有操作,并纠正任何故障。您还可以查找您的类的任何导入/实例化。

    【讨论】:

      【解决方案5】:

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

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

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

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

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

      【讨论】:

      • 关于第 3 点的问题:如果正确测试公共代码,实例化是否也必须进行“单元”测试?或者它只是第一次强制正确实现公共代码的一种方式,编写多个实现之前?
      • 好的单元测试,测试一个类或函数的行为是否符合预期。然后,您可以进行不同的测试层,即集成或功能测试。这些可能会像黑盒一样驱动应用程序,或者它们可能只是看到您调用顶级功能时会发生什么。
      • @Joël common codeinstantiations 之间的区别让人感觉很随意,并且可能会随着代码的发展而改变。您可以选择单元测试涵盖的内容,典型的地方是在不同抽象级别划分接口和实现的行。
      猜你喜欢
      • 1970-01-01
      • 2022-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-17
      • 2010-11-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多