给C#程序员编写Python的建议[关闭]


72

在过去的几年中,我主要从事C#开发,但最近开始做一些Python(不是Iron Python)。但是我不确定我是否已经在精神上飞跃到Python ...我觉得我正在尝试像在C#中那样做事情。

关于如何充分利用Python的任何建议?

还是任何技巧,窍门,需要更多了解的东西,需要注意的事情?


10
您甚至意识到自己正在使用C#习惯,这一事实表明,当大多数人开始使用一种新语言时,您已经远远领先于所有人:)
Jon Skeet

Answers:


155

首先,检查tgrayLundström的建议。

然后,您可能想知道一些事情:

  • Python是动态类型的,因此与C#不同,您将不检查类型,而是检查行为。您可能想在Google上搜索鸭子的类型。这意味着您不必处理装箱和拆箱。

  • Python是完全面向对象的,但是语法没有强制这种范例。您无需使用“类”一词就可以编写Python。

  • Python所具有的GUI库无法与C#相比。检查PyQt,GTK或wxPython库。

  • Python有许多您可能不熟悉的概念:列表理解,生成器(C#中确实存在“ yield”,但使用率不高),装饰器,元类等。您可以在没有它们的情况下使用Python进行编程。它们只是智能工具,不是强制性的。

  • 像在C#中一样,Python标准库非常庞大。遇到任何问题时,请务必看一看。很有可能有人已经解决了。

  • Python使用LATE绑定和变量标签。对于开始使用该语言的人来说,现在担心还为时过早,但是请记住,有一天您会遇到一种行为,该行为带有SEEMS不合逻辑的变量,因此您必须进行检查。目前:

请记住不要执行以下操作:

def myfunc(my_list=[]) :
   # bla

代替:

def myfunc(my_list=()) :
   my_list = list(my_list)

而且你会很好。有充分的理由,但这不是重点:-)

  • Python是跨平台的,可以在Mac上进行编写,并且可以根据需要在Linux上运行。

  • 复杂的IDE不提供Python(您获得IDLE :-))。如果您是Visual Studio的迷,请检查Glade。它不像Visual Studio先进,但是仍然是一个不错的RAD

  • 如果要使用Python开发某些Web应用程序,请记住Python不是.NET。如果要比较,必须向其中添加一个Web框架。我喜欢Django

  • Python不需要庞大的IDE。SciTENotepad ++IDLEKategedit ...轻量级的编辑器确实足够了。

  • Python使用空格和换行符强制执行缩进,您无法更改。您应避免使用制表符缩进,而应选择空格。空的手镯{}相当于关键字“ pass”。

  • Python不强制使用私有变量。您可以在变量名的开头使用“ __”(两个下划线)来定义一个私有变量,但是它仍然可以通过一些棘手的方式绕过。Python通常假设程序员是成年人,他们知道他们的工作和进行交流。

  • Python使用迭代。很多。很多很多。因此,itertools模块是您最好的朋友。

  • Python没有内置的委托。委托模块不是您所想的。对于事件驱动的编程,请使用GUI库(或自己编写模式,这并不困难)。

  • Python有一个解释器:您可以实时测试几乎所有内容。它应始终在文本编辑器旁边运行。Python基本的解释器并不多,请尝试IPython 以获得一些好吃的东西。

  • Python已自动记录:在您自己的代码中使用docstrings,并在python解释器中使用“ help()”咨询其他人

模块基础:

  • sys:操纵系统功能
  • os:设置凭据,操纵文件路径,重命名,递归文件遍历等
  • shutil:批处理文件(例如递归删除)
  • 回复:正则表达式
  • urllib和urllib2:HTTP脚本,例如下载,发布/获取请求等。
  • datetime:操作日期,时间和持续时间
  • 线程:你猜对了
  • zlib:压缩
  • 泡菜:序列化
  • xml:使用SAX或DOM解析/编写XML

有数百个模块。请享用。

在Python中执行操作的一些典型方法:

循环:

Python编码人员大量使用等效于foreachC#循环的方法,并且比其他任何方法都喜欢它:

基本迭代:

for item in collection:
    print str(item)

“集合”可以是字符串,列表,元组...任何可迭代的:定义.next()方法的任何对象。Python中有很多可迭代项。例如:读取文件的典型Python习惯用法:

for line in open("/path/to/file") :
    print line

for循环的快捷方式称为“列表理解”。这是一种在一行中创建新的可迭代对象的方法:

创建具有列表理解的过滤列表:

my_list = [item for item in collection if condition]

创建一个具有列表理解的新列表:

my_list = [int(item) * 3 for item in collection]

创建一个具有列表理解的新生成器:

my_list = (int(item) * 3 for item in collection)

与上面相同,但是这些值将在第一次迭代时即时生成,然后丢失。有关此的更多信息。

普通的循环

如果要表达通常的for循环,可以使用xrange()函数。for (int i = 0; i < 5; i++)变成:

for i in xrange(0,5) :

等效地做

Python中没有“ Do While”。我从未错过过它,但是如果您必须使用此逻辑,请执行以下操作:

while True : # Yes, this is an infinite loop. Crazy, hu?

  # Do your stuff

  if condition :
      break

开箱

交换变量:

a, b = b, a

多项分配:

以上只是我们所谓的“拆包”(此处适用于元组)的结果。一种简单的解释方法是,您可以在一行中将任何序列的每个值直接分配给相等数量的变量:

animal1, animal2, animal3, animal4 = ["cow", "dog", "bird", "fish"]

这有很多含义。在多维数组上进行迭代时,通常一个子序列一个接一个地使用,例如:

agenda = [("steve", "jobs"), ("linus", "torvald"), ("bill", "gates"),("jon", "skeet")]
for person in agenda:
    print person[0], person[1]

但是,通过解压缩,您还可以将值直接分配给变量:

agenda = [("steve", "jobs"), ("linus", "torvald"), ("bill", "gates"),("jon", "skeet")]
for name, lastname in agenda:
    print name, lastname

这就是为什么如果要在迭代时获取索引,Python编码人员将使用以下惯用法(enumerate()是标准函数):

for index, value in enumerate(sequence) :
    print index, value

在函数调用中解包

这是高级用法,如果您感到困扰,可以跳过它。

您可以使用符号“ *”解包值,以直接在函数调用中使用序列。例如:

>>> foo(var1, var1, var3) :
    print var1, var2
    print var3
>>> seq = (3.14, 42, "yeah")
>>> foo(*seq)
3.14 42
yeah

不仅如此。你可以解开一个字典作为命名的变量,并用写函数原型***接受参数的任意数量。但是它用的不够多,不值得使这篇文章更长:-)。

字符串格式:

print "This is a %s on %s about %s" % ("post", "stackoverflow", "python")
print "This is a %(subject)s on %(place)s about %(about)s" % {"subject" : "post", "place" : "stackoverflow", "about" : "python"}

切片可迭代对象:

您可以使用非常简洁的语法获取可迭代的任何部分:

print "blebla"[2:4] # Print "eb"
last = string[:-1] # Getting last element
even = (0,1,2,3,4,5,6,7,8,9)[::2] # Getting evens only (third argument is a step)
reversed = string[::-1] # Reversing a string

逻辑检查:

您可以检查在C#中的执行方式,但是有“ Pythonic”方式(更短,更清晰:-)):

if 1 in (1, 2, 3, 4) : # Check en element is in a sequence

if var : # check is var is true. Var == false if it's False, 0, (), [], {} or None

if not var : # Contrary of above

if thing is var: # Check if "thing" and "var" label the same content.

if thing is None : # We use that one because None means nothing in Python (almost null)

组合(在一行上以大写形式显示所有包含“ o”的单词):

sentence = "It's a good day to write some code"
print " ".join([word.upper() for word in sentence.split() if "o" in word])

输出:“良好的某些代码”

寻求宽恕比允许容易

Python编码人员通常不会检查是否有可能。他们有点像查克·诺里斯(Chuck Norris)。他们做到了。然后捕获异常。通常,您不检查文件是否存在,而是尝试打开它,如果失败则回滚:

try :
    f = open(file)
except IOerror :
    print "no file here !"

当然,查克·诺里斯(Chuck Norris)从不使用例外,因为他从未失败。

else子句

“其他”在Python中有许多用途。您会在“ if”之后找到“ else”,但也会在“ except”和“ for”之后找到。

for stuff in bunch :
    # Do things
else :
    # This always happens unless you hit "break" in the loop

即使我们没有过多地使用此循环,这也适用于“ while”循环。

   try :
      # A crazy stuff
   except ToCrazyError :
      # This happens if the crazy stuff raises a ToCrazyError Exception
   else :
      # This will happen if there is no error so you can put only one line after the "try" clause
   finally :
      # The same as in C#

如果您好奇的话,这里有一些高级的快速而肮脏的(但不错的)Python片段


1
令人印象深刻!我会说两件事:1.将elementtree用于xml。2.变量交换是元组拆包的一个示例;您可能想提一下包装,因为您是如此的全面:-)
John Fouhy 2009年

+1是一个不错的链接sebsauvage.net/python/snyppets/index.html如果您想了解更多有关GUI编程的信息,那么它是一个非常好的示例。
马丁

@Fouhy:元素树+1。但是我尝试远离非标准库,同时向新手解释Python。太多的好东西令人恐惧:-)收入1000 GUI库令人震惊:-)您是正确的解压缩者。我正在寻找一种简单的方法来解释它,一旦获得它就回来。
e-satis

4
+1令人印象深刻
Mizipzor 2010年

3
哇,当他们说python-ists对新手很好时,他们不是在开玩笑!
gideon

16
  • 避免使用类。使用字典,集合,列表和元组。
  • 禁止使用二传手和吸气剂。
  • 除非确实需要,否则不要有异常处理程序-让它崩溃。
  • Pylint可以成为您的朋友,以获得更多pythonish编码风格。
  • 准备就绪后,请查看列表推导,生成器和lambda函数。

我同意并增加了+1,但对第三点有些不同意,我认为在代码逻辑中使用异常处理程序实际上是pythonic的(又名“先请求宽恕然后再获得许可更容易”)。
ChristopheD

1
“守信者是吸气剂的混蛋。” -英语不合格?我不太明白
斯特雷格2009年

@strager:我读它的意思是“不允许您写setter和getters”(或者:“您不鼓励写...”)。怎么了
Joachim Sauer,2009年

关键是应该认为设置方法和获取方法就像被禁止一样。您可以编写它们,但是大多数都会问为什么?为什么不使用该属性?为什么不定义属性?
S.Lott

1
@Jason Baker:好吧,这是给C#程序员的建议,他可能会为python已经具有丰富选择选项的数据容器创建类。
StefanLundström,2009年

13

如果您不是编程新手,我会推荐Mark Pilgrim的《 Dive into Python》一书。它以一种易于理解的方式解释了Python,该方法如何将Python技术和习惯用法应用于构建实际应用程序。


6

首先阅读Python的禅宗

您可以在上面的链接中阅读它,也可以import this在Python提示符下键入。=)

利用C#不提供的Python功能*

例如鸭式打字,元类,列表理解等*

编写简单的程序只是为了测试这些功能。您很快就会习惯(如果不上瘾的话)他们。

看一下Python标准库

因此,您不必重新发明轮子。不要试图阅读整个内容,即使快速浏览一下TOC也可以节省大量时间。


*我知道C#已经具有其中一些功能,但是从我的眼中看,它们不是很新,还是C#开发人员不常用的功能。如果我错了,请纠正我。


1
您是否真的认为python新手应该弄乱元类?
John Fouhy

1
@John:当然,为什么不呢?元类不是一个大的红色按钮,上面写着“开始核战争”。最坏的情况是他的程序不起作用。他如何在不弄脏双手的情况下学习Python?=)
Can BerkGüder09年

经过数年的Python,我开始了解元类。我可能比普通程序员要愚蠢,但我不建议这样做。
e-satis

我是Python的新手,如果有人告诉我不要使用“元类”,那么我现在将找到使用它们的“需要”。自PowerBuilder以来,最有趣的时间是我学习一种新语言。Java并没有为我做这件事,Javascript很棒,但是良好的框架却被Telerik和Kendo等卑鄙的公司从开源社区盗窃,这些公司以使勒索感觉良好的价格出售社区设计的软件。
Rich Bianco


3

如果您是一个最好的人,只需通过少量的逐步学习就能学习一种新语言,那么我建议您使用IronPython。否则,请使用常规的CPython,并且在您不了解Python之前不要再进行任何C#编码。


4
除了不再进行C#编码以外,它还有助于停止冲洗和剃刮。
alex 2009年

您会在学习中文或日语时停止讲英语吗?
Teoman shipahi 2014年

好点子。在掌握Python之前,我将暂缓Angular,Phalcon PHP,.NET核心和.NET MVC。将剃须刀移动到电动剃须刀上,这样您就可以在观看培训视频时做到这一点-直到我们可以像Neo一样学习为止……“我知道柔术吗?”
Rich Bianco

2

我建议您找一个好的编辑器,以免被空格所困扰。为简单起见,我只使用ActivePython的软件包Link,其中包括一个编辑器和所有win32api库。如果您一直在使用C#,它们很有趣。Python中的win32api可能会更简单一些。您不需要做整个DDLImport事情。下载ActivePython(CPython随附),将其打开,然后开始在控制台中输入一些内容。使用C#之后,您将非常容易地将其拾起。对于一些更有趣的Python技巧,请尝试ActiveState代码,其中包含各种配方,可以使您非常简单地看到可以使用Python进行的不同操作。


+1-几乎无法以编程方式安装pywin32,因此在安装python时不妨将其删除。
杰森·贝克

我很高兴看到隧道尽头的灯光,直到不再需要Windows为止。.NET有许多好的替代品。微软在Windows 10上挖了自己的坟墓,我从来都不是Linux的拥护者,但是当它开始自我毁灭时,我尝试了一下Zorin,两个星期后-不再渴望或不需要启动windoze。
Rich Bianco

2

我也很忙,大部分工作仍在使用C#,但在其他项目中则越来越多地使用Python。

@ e-satis可能完全了解Python,他的所有建议都是一流的。从我的角度来看,对我最大的影响是:

恢复功能。不一定是意大利面条式的代码,而是要知道并非所有内容都必须在对象中,也不应该在对象中。

口译员。就像立即窗口一样,只好10 ^ 10。由于Python的工作方式,您不需要所有的包and和垃圾,而C#可以让您在开始运行之前就放心了。您可以只打几行,看看情况如何。

我通常有一个IDLE实例,在编辑文件时,我正在四处寻找代码片段的工作方式,例如,忙着研究如何在地图上进行地图调用列表,但我不是应该使用的Lambda的100%……在IDLE中插入几行,看看其工作原理和作用。

最后,我喜欢Python的冗长性,我的意思并不是冗长的冗长含义,而是正如e-satis所指出的那样,使用“ in”,“ is”,“ for”等动词。

如果您在C#中做了很多反射工作,当您看到Python中的相同内容多么简单时,您会感到哭泣。

祝你好运。


反射是我有几年光经验还没有完全掌握的点网的一个领域。我的主要专长是PowerBuilder,它完全面向对象,包括可视对象继承。希望Python比点网更面向对象。
Rich Bianco


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.