我的大部分编程背景都是用Java编写的,而且我仍在用Java编写大部分编程。但是,我开始学习Python在工作中的一些副项目,我想学习它尽可能独立于我的Java背景 - 即我不想只用Python编写Java。我应该注意哪些事情?
一个简单的例子 - 在查看Python教程时,我发现了一个函数(例如列表)的默认可变参数被保留(从调用到调用记住)的事实。这对我作为Java程序员来说是违反直觉的,很难让我理解。 (如果您不理解该示例,请参阅here和here。)
有人还向我提供了this列表,我觉得这很有帮助,但很简短。任何人都有任何其他Java程序员可能会滥用Python的例子......?或者Java程序员会错误地假设或难以理解的东西?
编辑:好的,简要概述了我链接到的文章所解决的原因,以防止答案中出现重复(正如Bill the Lizard所建议的那样)。 (如果我在措辞上犯了错误,请告诉我,我只是只是从Python开始,所以我可能不完全理解所有概念。而且免责声明 - 这些将是非常简短,所以如果你在检查链接时不明白它会得到什么。)
(如果你觉得这个问题很有意思,请查看链接。:)非常好。)
答案 0 :(得分:24)
这样做:
class Dog(object):
def make_sound(self):
return "woof!"
class Cat(object):
def make_sound(self):
return "meow!"
class LolCat(object):
def make_sound(self):
return "i can has cheezburger?"
答案 1 :(得分:22)
引用的文章有一些很好的建议,很容易被误引和误解。还有一些不好的建议。
让Java落后。重新开始。 “不要相信你的[基于Java]的直觉”。说事情“反直觉”是任何编程学科的坏习惯。学习一门新语言时,重新开始,放弃自己的习惯。你的直觉必须是错误的。
语言不同。否则,它们将是具有不同语法的相同语言,并且会有简单的翻译器。因为没有简单的翻译器,所以没有简单的映射。这意味着直觉是无益和危险的。
“Java中的静态方法不能转换为Python类方法。”这种事情真的有限且无益。 Python有一个staticmethod装饰器。它还有一个classmethod装饰器,Java没有相应的装饰器。
这一点,BTW,还包括更有帮助的建议,不要在课堂上不必要地包装所有内容。 “Java静态方法的惯用翻译通常是模块级函数”。
Java中的Java switch
语句可以通过多种方式实现。首先,它通常是if elif elif elif
构造。这篇文章在这方面没有任何帮助。如果您完全确定这太慢(并且可以证明它),您可以使用Python字典作为从值到代码块的稍快的映射。盲目地将开关转换为字典(不加思考)是非常糟糕的建议。
不要使用XML。脱离背景时没有意义。在上下文中,它意味着不依赖于XML来增加灵活性。 Java依赖于描述XML中的东西;例如,WSDL文件重复从检查代码中可以明显看出的信息。 Python依赖于内省,而不是用XML重述所有内容。
但是Python拥有出色的XML处理库。几个。
Getter和setter在Python中不是必需的,因为它们在Java中是必需的。首先,您在Python中有更好的内省,因此您不需要getter和setter来帮助创建动态bean对象。 (为此,您使用collections.namedtuple)。
但是,你有property装饰器,它将把getter(和setter)捆绑成一个类似属性的构造。关键是Python更喜欢裸露的属性;必要时,我们可以将getter和setter捆绑在一起,看起来好像有一个简单的属性。
此外,如果属性不够复杂,Python也有描述符类。
代码重复通常是Java中必不可少的恶魔(例如方法重载),但在Python中则不然。正确。 Python使用可选参数而不是方法重载。
接下来要谈谈关闭;这不如明智地使用默认参数值的简单建议那么有用。
答案 2 :(得分:13)
您在Python中可能习惯的一件事是您在Python中找不到的是严格的隐私。这不是一件需要注意的事情,因为它是不要寻找的东西(当我开始时我搜索了一个等同于'private'的Python多久了,我感到很尴尬!)。相反,Python比Java更透明,更容易内省。这属于有时被描述为“我们都同意成年人在这里”的哲学。有一些约定和语言机制可以帮助防止意外使用“非公共”方法等等,但Python中几乎没有信息隐藏的整体思维模式。
答案 3 :(得分:9)
我能想到的最大问题是不了解或不充分利用鸭子打字。在Java中,您需要预先指定非常明确和详细的类型信息。在Python中,输入既是动态的,也是隐含的。理念是你应该在比名义类型更高的层次上考虑你的程序。例如,在Python中,您不使用继承来模拟可替代性。由于鸭子打字,默认情况下可替代性。继承只是程序员重用实现的便利。
同样,Pythonic成语是“请求宽恕,不要求许可”。明确的打字被认为是邪恶的。不要事先检查参数是否某种类型。只是尝试做任何你需要做的参数。如果它不符合正确的接口,它将抛出一个非常明确的异常,你将能够很快找到问题。如果有人传递了一个名义上意外但与你的预期界面相同的类型的参数,那么你就可以获得免费的灵活性。
答案 4 :(得分:6)
最重要的是,从Java POV来看,完全可以不为所有内容创建类。在许多情况下,程序方法更简单,更短。
接下来最重要的是你必须克服一个对象的类型控制它可能做什么的概念;相反,代码控制哪些对象必须能够在运行时支持 (这是由于鸭子类型)。
哦,尽可能使用原生列表和dicts(不是自定义的后代)。
答案 5 :(得分:5)
Python中处理异常的方式不同于 如何用Java处理它们。而在Java中的建议 是仅在特殊情况下使用例外而不是 所以使用Python。
在Python中,像Iterator这样的东西使用异常机制来表示没有更多的项目。但是这样的设计在Java中不被认为是好的做法。
Alex Martelli在他的书中提到Python in a Nutshell 与其他语言的异常机制(适用于Java) 是 LBYL (在你跳跃之前看): 在尝试操作之前,应提前检查可能导致操作无效的所有情况。
与Python一样,这种方法是EAFP(要求宽恕比允许更容易)
答案 6 :(得分:1)
“不要为所有事情使用类”的改编:回调。
用于执行回调的Java方法依赖于传递实现回调接口的对象(例如ActionListener
及其actionPerformed()
方法)。 Python中不需要这种类型,您可以直接传递方法甚至是本地定义的函数:
def handler():
print("click!")
button.onclick(handler)
甚至是lambdas:
button.onclick(lambda: print("click!\n"))