java 作为学习Python的Java程序员,我应该注意什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2339371/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
As a Java programmer learning Python, what should I look out for?
提问by froadie
Much of my programming background is in Java, and I'm still doing most of my programming in Java. However, I'm starting to learn Python for some side projects at work, and I'd like to learn it as independent of my Java background as possible - i.e. I don't want to just program Java in Python. What are some things I should look out for?
我的大部分编程背景都是用 Java 编写的,而且我的大部分编程工作仍然用 Java 编写。但是,我开始为工作中的一些副项目学习 Python,并且我想尽可能独立于我的 Java 背景来学习它 - 即我不想只用 Python 编写 Java。我应该注意哪些事项?
A quick example - when looking through the Python tutorial, I came across the fact that defaulted mutable parameters of a function (such as a list) are persisted (remembered from call to call). This was counter-intuitive to me as a Java programmer and hard to get my head around. (See hereand hereif you don't understand the example.)
一个简单的例子 - 在查看 Python 教程时,我发现函数(例如列表)的默认可变参数是持久化的(从调用到调用记住)。作为一名 Java 程序员,这对我来说是违反直觉的,而且很难理解。(如果您不理解示例,请参阅此处和此处。)
Someone also provided me with thislist, which I found helpful, but short. Anyone have any other examples of how a Java programmer might tend to misuse Python...? Or things a Java programmer would falsely assume or have trouble understanding?
有人还向我提供了这个列表,我发现它很有帮助,但很简短。任何人都有其他关于 Java 程序员可能会如何滥用 Python 的例子......?或者 Java 程序员会错误地假设或难以理解的事情?
Edit: Ok, a brief overview of the reasons addressed by the article I linked to to prevent duplicates in the answers (as suggested by Bill the Lizard). (Please let me know if I make a mistake in phrasing, I've only juststarted with Python so I may not understand all the concepts fully. And a disclaimer - these are going to be verybrief, so if you don't understand what it's getting at check out the link.)
编辑:好的,简要概述我链接到的文章所解决的原因,以防止答案中的重复(如比尔蜥蜴所建议)。(如果我在措辞上犯了错误,请告诉我,我刚刚开始使用 Python,所以我可能无法完全理解所有概念。免责声明 - 这些将非常简短,所以如果你不明白请查看链接中的内容。)
- A static method in Java does not translate to a Python classmethod
- A switch statement in Java translates to a hash table in Python
- Don't use XML
- Getters and setters are evil (hey, I'm just quoting :) )
- Code duplication is often a necessary evil in Java (e.g. method overloading), but not in Python
- Java 中的静态方法不会转换为 Python 类方法
- Java 中的 switch 语句转换为 Python 中的哈希表
- 不要使用 XML
- getter 和 setter 是邪恶的(嘿,我只是引用:))
- 代码重复在 Java 中通常是一种必要的邪恶(例如方法重载),但在 Python 中则不然
(And if you find this question at all interesting, check out the link anyway. :) It's quite good.)
(如果您觉得这个问题很有趣,请查看链接。:) 这很好。)
采纳答案by Ryan Ginstrom
- Don't put everything into classes. Python's built-in list and dictionaries will take you far.
- Don't worry about keeping one class per module. Divide modules by purpose, not by class.
- Use inheritance for behavior, not interfaces. Don't create an "Animal" class for "Dog" and "Cat" to inherit from, just so you can have a generic "make_sound" method.
- 不要把所有东西都放在类中。Python 的内置列表和词典将带您走得更远。
- 不要担心每个模块保留一个类。按目的划分模块,而不是按类。
- 对行为使用继承,而不是接口。不要为“狗”和“猫”创建一个“动物”类来继承,这样你就可以有一个通用的“make_sound”方法。
Just do this:
只需这样做:
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?"
回答by S.Lott
The referenced article has some good advice that can easily be misquoted and misunderstood. And some bad advice.
引用的文章有一些很好的建议,很容易被错误引用和误解。还有一些不好的建议。
Leave Java behind. Start fresh. "do not trust your [Java-based] instincts". Saying things are "counter-intuitive" is a bad habit in any programming discipline. When learning a new language, start fresh, and drop your habits. Your intuition mustbe wrong.
将 Java 抛在脑后。开始新鲜。“不要相信你的 [基于 Java 的] 直觉”。说事情“违反直觉”在任何编程学科中都是一个坏习惯。学习一门新语言时,重新开始,摒弃你的习惯。你的直觉一定是错误的。
Languages are different. Otherwise, they'd be the same language with different syntax, and there'd be simple translators. Because there are not simple translators, there's no simple mapping. That means that intuition is unhelpful and dangerous.
语言不同。否则,它们将是具有不同语法的相同语言,并且会有简单的翻译器。因为没有简单的翻译器,所以没有简单的映射。这意味着直觉是无益和危险的。
"A static method in Java does not translate to a Python classmethod." This kind of thing is really limited and unhelpful. Python has a staticmethoddecorator. It also has a classmethoddecorator, for which Java has no equivalent.
This point, BTW, also included the much more helpful advice on not needlessly wrapping everything in a class. "The idiomatic translation of a Java static method is usually a module-level function".
The Java
switchstatement in Java can be implemented several ways. First, and foremost, it's usually anif elif elif elifconstruct. The article is unhelpful in this respect. If you're absolutely sure this is too slow (and can prove it) you can use a Python dictionary as a slightly faster mapping from value to block of code. Blindly translating switch to dictionary (without thinking) is really bad advice.Don't use XML. Doesn't make sense when taken out of context. In context it means don't rely on XML to add flexibility. Java relies on describing stuff in XML; WSDL files, for example, repeat information that's obvious from inspecting the code. Python relies on introspection instead of restating everything in XML.
But Python has excellent XML processing libraries. Several.
Getters and setters are not requiredin Python they way they're required in Java. First, you have better introspection in Python, so you don't need getters and setters to help make dynamic bean objects. (For that, you use collections.namedtuple).
However, you have the propertydecorator which will bundle getters (and setters) into an attribute-like construct. The point is that Python prefers naked attributes; when necessary, we can bundle getters and setters to appear as if there's a simple attribute.
Also, Python has descriptor classes if properties aren't sophisticated enough.
Code duplication is often a necessary evil in Java (e.g. method overloading), but not in Python. Correct. Python uses optional arguments instead of method overloading.
The bullet point went on to talk about closure; that isn't as helpful as the simple advice to use default argument values wisely.
“Java 中的静态方法不会转换为 Python 类方法。” 这种事情真的很有限,也无济于事。Python 有一个静态方法装饰器。它还有一个classmethod装饰器,Java 没有与之等效的装饰器。
顺便说一句,这一点还包括关于不要在类中不必要地包装所有内容的更有用的建议。“Java 静态方法的惯用翻译通常是模块级函数”。
Java
switch中的 Java语句可以通过多种方式实现。首先,也是最重要的,它通常是一个if elif elif elif构造。这篇文章在这方面没有帮助。如果您绝对确定这太慢(并且可以证明这一点),您可以使用 Python 字典作为从值到代码块的稍微快一点的映射。盲目地将 switch 翻译成字典(不假思索)是非常糟糕的建议。不要使用 XML。脱离上下文没有意义。在上下文中,这意味着不要依赖 XML 来增加灵活性。Java 依赖于用 XML 描述内容;例如,WSDL 文件会重复通过检查代码显而易见的信息。Python 依赖于自省而不是在 XML 中重述所有内容。
但是 Python 具有出色的 XML 处理库。一些。
Python 中不需要getter 和 setter ,它们在 Java 中是必需的。首先,您在 Python 中有更好的内省,因此您不需要 getter 和 setter 来帮助创建动态 bean 对象。(为此,您使用collections.namedtuple)。
但是,您拥有属性装饰器,它将 getter(和 setter)捆绑到一个类似属性的构造中。关键是 Python 更喜欢裸属性;必要时,我们可以捆绑 getter 和 setter,使其看起来好像有一个简单的属性。
此外,如果属性不够复杂,Python 有描述符类。
代码重复在 Java 中通常是一种必要的邪恶(例如方法重载),但在 Python 中则不然。正确的。Python 使用可选参数而不是方法重载。
要点继续讨论关闭;这不像明智地使用默认参数值的简单建议那么有用。
回答by John Y
One thing you might be used to in Java that you won't find in Python is strict privacy. This is not so much something to look out for as it is something notto look for (I am embarrassed by how long I searched for a Python equivalent to 'private' when I started out!). Instead, Python has much more transparency and easier introspection than Java. This falls under what is sometimes described as the "we're all consenting adults here" philosophy. There are a few conventions and language mechanisms to help prevent accidentaluse of "unpublic" methods and so forth, but the whole mindset of information hiding is virtually absent in Python.
您可能在 Java 中习惯了在 Python 中找不到的一件事是严格的隐私。这与其说是值得关注的东西,不如说是不值得关注的东西(当我开始时,我搜索了相当于“私有”的 Python 的时间,这让我感到尴尬!)。相反,Python 比 Java 具有更高的透明度和更容易的内省。这属于有时被描述为“我们都同意这里的成年人”的哲学。有一些约定和语言机制可以帮助防止意外使用“非公共”方法等,但是 Python 中几乎没有信息隐藏的整个思维方式。
回答by dsimcha
The biggest one I can think of is not understanding or not fully utilizing duck typing. In Java you're required to specify very explicit and detailed type information upfront. In Python typing is both dynamic and largely implicit. The philosophy is that you should be thinking about your program at a higher level than nominal types. For example, in Python, you don't use inheritance to model substitutability. Substitutability comes by default as a result of duck typing. Inheritance is only a programmer convenience for reusing implementation.
我能想到的最大的问题是不理解或没有充分利用鸭子类型。在 Java 中,您需要预先指定非常明确和详细的类型信息。在 Python 中,类型既是动态的,又是隐式的。哲学是你应该在比名义类型更高的层次上考虑你的程序。例如,在 Python 中,您不使用继承来模拟可替换性。默认情况下,可替代性是鸭子类型的结果。继承只是程序员重用实现的便利。
Similarly, the Pythonic idiom is "beg forgiveness, don't ask permission". Explicit typing is considered evil. Don't check whether a parameter isa certain type upfront. Just try to do whatever you need to do with the parameter. If it doesn't conform to the proper interface, it will throw a very clear exception and you will be able to find the problem very quickly. If someone passes a parameter of a type that was nominally unexpected but has the same interface as what you expected, then you've gained flexibility for free.
同样,Pythonic 的成语是“乞求宽恕,不要征得许可”。显式类型被认为是邪恶的。不要预先检查参数是否是某种类型。只需尝试对参数执行任何您需要执行的操作即可。如果它不符合正确的接口,它会抛出一个非常明确的异常,你将能够很快找到问题。如果有人传递了一个名义上出乎意料的类型的参数,但具有与您预期相同的接口,那么您就免费获得了灵活性。
回答by Caleb Hattingh
The most important thing, from a Java POV, is that it's perfectly ok to not make classes for everything. There are many situations where a procedural approach is simpler and shorter.
最重要的是,从 Java POV 来看,不为所有东西都创建类是完全可以的。在许多情况下,程序方法更简单、更短。
The next most important thing is that you will have to get over the notion that the typeof an object controls what it may do; rather, the codecontrols what objects must be able to support at runtime(this is by virtue of duck-typing).
下一个最重要的事情是你必须克服对象的类型控制它可以做什么的观念;相反,代码控制在运行时必须能够支持哪些对象(这是由于鸭子类型)。
Oh, and use native lists and dicts (not customized descendants) as far as possible.
哦,尽可能使用原生列表和字典(不是自定义的后代)。
回答by sateesh
The way exceptions are treated in Python is different from how they are treated in Java. While in Java the advice is to use exceptions only for exceptional conditions this is not so with Python.
Python 中处理异常的方式与 Java 中处理异常的方式不同。虽然在 Java 中的建议是仅在异常情况下使用异常,但 Python 并非如此。
In Python things like Iterator makes use of exception mechanism to signal that there are no more items.But such a design is not considered as good practice in Java.
在 Python 中,诸如 Iterator 之类的东西使用异常机制来表示没有更多项目。但这种设计在 Java 中不被视为良好实践。
As Alex Martelli puts in his book Python in a Nutshellthe exception mechanism with other languages (and applicable to Java) is LBYL(Look Before You Leap) : is to check in advance, before attempting an operation, for all circumstances that might make the operation invalid.
正如 Alex Martelli 在他的Python in a Nutshell一书中所说 ,其他语言(适用于 Java)的异常机制是LBYL(Look Before You Leap):是在尝试操作之前提前检查所有可能导致操作无效。
Where as with Python the approach is EAFP (it's easier to Ask for forgiveness than permission)
与 Python 一样,方法是 EAFP(请求宽恕比许可更容易)
回答by Rafa? Dowgird
A corrollary to "Don't use classes for everything": callbacks.
“不要为所有事情使用类”的推论:回调。
The Java way for doing callbacks relies on passing objects that implement the callback interface (for example ActionListenerwith its actionPerformed()method). Nothing of this sort is necessary in Python, you can directly pass methods or even locally defined functions:
执行回调的 Java 方式依赖于传递实现回调接口的对象(例如ActionListener使用其actionPerformed()方法)。Python 中不需要这种类型,您可以直接传递方法甚至本地定义的函数:
def handler():
print("click!")
button.onclick(handler)
Or even lambdas:
甚至 lambda 表达式:
button.onclick(lambda: print("click!\n"))

