学习Python的Java开发人员:我需要包扎哪些概念?


38

背景:我已经完成了一些教程并编写了一些小项目。使用Google和StackOverflow一切都很好。

在过去的几天里,我几次想知道“我想念什么?” -我觉得我在用Python编写代码时仍在思考Java。

StackOverflow上的这个问题充满了关于学习Python需学习哪些资源的提示,但我仍然觉得我是Java开发人员,有字典(无需双关语)可以翻译成Python。

我真正想做的是重构我的头脑,使其能够编写Pythonic Python而不是伪装成Python的Java,而又不会失去我的Java技能。

因此,我的问题的症结在于:Java开发人员真正需要学习什么概念才能思考Pythonic?这包括需要学习的所有内容。

注意:我是在询问语言概念,而不是语言语法。


9
放开编程应该很难的想法。
工作

Answers:


40

除了已经说过的几点以外:

  • Python是动态的。类的创建是可执行语句,模块的导入也是如此。可以使其成为有条件的。创建后可以更改类;这样可以轻松进行元编程和AOP。

  • 没有接口; 鸭打字规则。如果您非常需要它们,则可以使用“抽象基类(ABC)”,但是通常您不会错过接口,因为无论如何都没有静态类型检查。

  • 尽管一切都是对象,但功能先于对象。在模块中仅包含函数(而没有类)完全可以。

  • 一切都是一流的实体。通常将函数作为参数传递,返回它们并分配给变量。同上课程。方法只是功能;您可以像处理常规方法一样处理实例方法,将其传递给其他对象,等等。

  • 使用内置的字典,集合,列表和元组。列表和字典是可变的,元组不是。它们都是非常有效的,并且语法简洁。习惯于使用元组从函数返回几个值(甚至不需要括号)。习惯于用由普通列表,元组和字典(“哈希表”)组成的装置替换非常简单的对象的复杂层次结构,从而简化了生活。

  • Python有很多FP支持。学习列表理解,然后学习迭代器和生成器。这些有很大帮助。

  • 通过定义适当的方法,任何运算符都可以重载,因此加法或比较可以返回您想要的任何内容。记住这与SQLAlchemy之类的东西一起工作。

  • 没有null,只有None,是一个完整的对象。您可以很好地打印None,等等。如果在其他实例预期未通过的地方传递None,通常会导致AttributeError而不是NPE,有时会在执行管道的最下方。

  • 由于Python具有完全动态的性质,因此几乎没有静态检查。您可以引用程序中不存在的名称(例如拼写错误),或者仅在特定的执行路径中定义该名称,并且在执行真正触及该引用并引发NameError之前,没有任何东西会提醒您。请注意变量的范围,并编写更多的单元测试。

  • 由于Python的完全动态特性,对象几乎总是可延展的。通常,您甚至可以向实例添加字段和方法,从而无意间删除或覆盖其状态或方法集。小心分配属性。这也提供了有趣的可能性:)

  • 没有符号常量,只有变量。检查您是否无意中覆盖了“常数”。如果您想确定不能覆盖常量,请使用函数或属性(伪装成函数)。

  • Python的线程适用于I / O绑定处理,但不适用于CPU绑定。不要试图通过在并行线程中运行来加快计算任务。


+1分非常好。细化:None通常会导致AttributeError(但没关系,无论如何您通常都不需要它),并且您可以(在某些情况下应该)编写不可变的对象(例如通过namedtuple)。

@danlan:谢谢,我纠正了文字:)是的,您可以创建不可变的对象。但是,除非您采取多种特殊措施,否则通常通过创建常规类然后再创建其实例来创建的对象是非常可变的。对未定义实例属性的分配通常以静默方式对其进行定义而不是引起错误,这一事实可能会使Java程序员感到惊讶。
9000

1
Python(和其他FP语言)用更复杂的构建块上的紧凑代码代替了更简单的构建块上的更详细的代码构建。想想RISC与CISC处理器。
保罗

1
我将集合添加到数据结构。
sakisk 2012年

2
自问这个问题以来已有3年多的时间了。我必须说这个建议站得很好。
LRE 2014年

14

阅读本文:Python不是Java。(此外,边栏中的其他大多数文章都值得一读,尽管与Java无关。)该文章为Java程序员如何无意间滥用Python(以及如何不正确使用)提供了一些很好的指导。


6
“ XML不是答案。” -远远超出了Java v Python ;-)
LRE

3

我从Java转到Python,发现的最有用的功能之一就是能够从命令行解释器测试代码。在命令行中输入python并从那里运行代码,直到正确为止。

框架在Python中的定义也较少。仅适用于初学者的Web框架有10多个。Django或多或少地将Spring和SQL Alchemy替换为Hibernate。


2

重要的一件事是了解动态类型;另一个是对象是可变的并且是公共的。至少在一开始,不重要的是名称绑定与变量。

class MyJob:
    pass        # an empty class
job = MyJob()
job.title = "Ruler of Omicron Persei 8"
job.startDate = "2086"
job.startDate = time.strptime("2035/01/02", "%Y/%m/%d")
myjobtitle = job.title
import new
def myjobduration(self, when):  # create a function
    return when - time.mktime(self.startDate)
MyJob.duration = myjobduration
job.duration(time.time()) # now

在这里,myjobtitle和job.title的值指向同一对象。首先为类属性job.startDate分配了一个字符串,然后分配了一个时间对象。整个过程,作业实例甚至类本身都可以动态更改。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.