我过去几年主要做C#开发,但最近开始做一些Python(不是Iron Python).但是我不确定我是否已经向Python进行了精神上的飞跃......我觉得我正在尝试按照C#中的方式做事.
关于如何充分利用Python的任何建议?
或者任何提示\技巧,要了解更多信息,需要注意的事项?
首先,检查tgray和Lundström的建议.
Python是动态类型的,因此与C#不同,您不会检查类型,而是检查行为.你可能想谷歌关于鸭子打字.这意味着你不必处理装箱和拆箱.
Python是完全面向对象的,但语法并没有强制执行这种范例.您可以在不使用"class"一词的情况下编写Python.
Python中使用的GUI库无法与C#进行比较.检查PyQt,GTK或wxPython库.
Python有很多你可能不熟悉的概念:列表推导,生成器("yield"确实存在于C#中,但它没有用得太多),装饰器,元类等等.不要害怕; 没有它们你可以用Python编程.它们只是智能工具,不是强制性的.
就像在C#中一样,Python标准库非常庞大.遇到任何问题时,请务必查看.很可能有人已经解决了它.
Python使用LATE绑定和变量标签.对于那些从语言开始担心它的人来说还为时过早,但请记住,有一天你会遇到一些变量看似不合逻辑的行为,你必须检查它.目前:
请记住永远不要做以下事情:
def myfunc(my_list=[]) : # bla
代替:
def myfunc(my_list=()) : my_list = list(my_list)
而且你会很好.有一个很好的理由,但这不是重点:-)
Python是跨平台的,喜欢在Mac上书写,如果你愿意,可以在Linux上运行.
Python没有提供复杂的IDE(你有IDLE :-)).如果您是Visual Studio上瘾者,请检查Glade.这不像Visual Studio那样先进,但它仍然是一个很好的RAD.
如果您想在Python中开发一些Web应用程序,请记住Python不是.NET.如果要进行比较,则必须向其添加Web框架.我喜欢Django.
Python不需要一个巨大的IDE来使用.SciTE, Notepad ++,IDLE,Kate,gedit ......轻量级编辑器已经足够了.
Python使用空格和换行符强制执行缩进,您无法更改.您应该避免使用制表符进行缩进,而是选择空格.空手镯{}的等价物是关键字"pass".
Python不强制实施私有变量.您可以在变量名称的开头使用"__"(两个下划线)定义私有变量,但它仍然可以通过一些棘手的方式绕过.Python通常假设程序员是成年人,知道他们做什么和沟通.
Python使用迭代.很多.很多很多.所以itertools模块是你最好的朋友.
Python没有内置的委托.委托模块不是您的想法.对于事件驱动的编程,使用GUI库(或者自己编写模式,并不困难).
Python有一个解释器:你几乎可以测试任何东西,直播.它应始终在文本编辑器旁边运行.Python的基本解释器并不多,尝试IPython可以获得 美味的东西.
Python是自动记录的:在你自己的代码中使用docstrings并在python解释器中使用"help()"来咨询其他人
sys:操纵系统功能
os:设置凭证,操纵文件路径,重命名,递归文件遍历等
shutil:批处理文件处理(如递归删除)
re:regexp
urllib和urllib2:HTTP编写脚本,如下载,发布/获取请求等.
日期时间:操纵日期,时间和持续时间
线程:你猜它
zlib:压缩
泡菜:序列化
xml:使用SAX或DOM解析/编写XML
有数百个模块.请享用.
Python编码器大量使用foreach
C#循环的等价物,并且更喜欢其他任何一个:
基本迭代:
for item in collection: print str(item)
"collection"可以是字符串,列表,元组......任何可迭代:定义.next()方法的任何对象.Python中有很多可迭代的东西.例如:读取文件的典型Python习语:
for line in open("/path/to/file") : print line
for循环的快捷方式称为"list comprehension".这是一种在一行中创建新迭代的方法:
使用列表推导创建筛选列表:
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"}
您可以使用非常简洁的语法获取iterable的任何部分:
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)
sentence = "It's a good day to write some code" print " ".join([word.upper() for word in sentence.split() if "o" in word])
输出:"好一些代码"
Python编码器通常不检查是否有可能.他们有点像查克诺里斯.他们这样做.然后抓住异常.通常,您不检查文件是否存在,尝试打开它,如果失败则回滚:
try : f = open(file) except IOerror : print "no file here !"
当然,查克诺里斯从未使用过,因为他从未失败过.
"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代码片段.
不要使用类.使用词典,集,列表和元组.
禁止使用限制器和吸气剂.
除非你真的需要,否则不要使用异常处理程序 - 让它崩溃.
Pylint可以成为更多蟒蛇编码风格的朋友.
准备好后 - 查看列表推导,生成器和lambda函数.
如果您不是编程新手,我会推荐Mark Pilgrim 撰写的"Dive into Python"一书.它以一种易于理解Python技术和习惯用法如何应用于构建实际应用程序的方式解释了Python.
首先阅读Python的Zen
您可以在上面的链接中阅读它,或者只需import this
在Python提示符下键入.=)
利用C#未提供的Python功能*
如鸭子打字,元类,列表理解等*
编写简单的程序只是为了测试这些功能.你很快就会被使用(如果不是上瘾的话).
查看Python标准库
所以你不要重新发明轮子.不要试图阅读整个事情,即使快速查看TOC也可以为您节省大量时间.
*我知道C#已经具备了一些这些功能,但从我所看到的它们要么是新的,要么是C#开发人员不常用的.如果我错了,请纠正我.
如果您还没有听说过,那么Dive Into Python是开始学习Python的好地方.它还有一堆提示和技巧.