您的位置:首页 > 编程语言 > Python开发

Python核心编程----Python基础

2016-07-05 18:55 232 查看
    本章目标:了解基本的Python语法,熟悉Python的编程风格。

                        了解标识符、变量和关键字。

                        了解变量占用的内存是如何分配和回收的。

                         第一个Python程序。

一、语法和句法

#  :表示之后的字符为Python注释;
\n :是标准的行分隔符(通常一个语句一行);
\   :继续上一行;
;   :将两个语句连接在一行中;
:   :将代码块的头和体分开;
代码块用缩进的方式体现;
不同的缩进深度表示不同的代码块;
Python文件以模块形式组织。
1.1  注释(#)

       从#开始,可以在一行任何地方开始,解释器会忽略掉改行#之后的所有内容。

1.2  继续(\)
       Python语句一般使用换行分隔,一行过长的语句可以使用 \ 来分成几行。
       #check conditions
       if (weather_is_hot == 1) and \
          (shark_warnings == 0):
              send_goto_beach_mesg_to_pager()

       有两种例外情况不使用反斜线也可以跨行。一个是使用闭合操作符时,比如含有小括号、中括号、花括号时;另一个是三引号包括下的字符串。

1.3  多个语句构成代码组(:)
       缩进相同的一组语句构成一个代码块,我们称之为代码组。例如:if 、while、 def 等复合语句,首行以关键字开始,以冒号结束,改行之后的一行或多行代码构成代码组。我们将首行及后面的代码组称为一个子句(clause)。

1.4  代码组由不同缩进分隔
           同一代码组的代码行必须严格左对齐。
        核心风格:缩进4个空格宽度,避免使用制表符。
        随着缩进深度的增加,代码块的层次也在加深,没有缩进的代码块是最高层次的,被称作脚本的“主体”(main)部分。
        
1.5  同一行书写多个语句(;)
        分号允许在一行中书写多个语句,而这些语句也不能在这行开始一个新的代码块。

1.6  模块
       每一个Python脚本文件都可以被当成是一个模块。模块以磁盘文件的形式存在。当一个模块变得过大,且驱动了太多功能的话,就需要考虑拆分一些代码块来另建一个模块。模块里的代码可以是一段直接执行的脚本,也可以是类似库函数的代码,从而可以被别的模块导入。


二、变量赋值

2.1  赋值操作符
       = 是Python中主要的赋值操作符。
       注意,赋值并不是直接将一个值赋给一个变量。在Python中,对象是通过引用传递的。在赋值时,不管这个对象是新创建的,还是一个已经存在的,都是将该对象的引用(而不是值)赋值给变量。
       在C语言中,赋值语句其实被当成一个表达式,可以返回值。但在Python中,并非如此,Python的赋值语句不会返回值。
       
>>> x = 1
>>> y = (x = x + 1)
File "<stdin>", line 1
y = (x = x + 1)
^
SyntaxError: invalid syntax


但是链式赋值是可以的
>>>y = x = x + 1
>>> x,y
(2, 2)


2.2  增量赋值
       x = x + 1         --->  x += 1
       增量赋值的意义在于,第一个对象仅被处理一次,可变对象会被就地修改,不可变对象则分配一个新对象。

2.3  多重赋值
       
>>> x = y = z = 5
>>> x
5
>>> y
5
>>> z
5


2.4  “多元”赋值
       
>>> x, y, z = 1, 2, 'abc'

>>> x
1

>>> y
2

>>> z
'abc'
       采用这种方式赋值,等号两边的对象都是元组。
       为了代码的可读性,建议两边加上括号。
   (x, y, z) = (1, 2, 'abc')

       多元赋值实现无需中间变量而交换两个变量的值。
>>> (x, y, z) = (1, 2, 'abc')

>>> x
1

>>> y
2

>>> z
'abc'

>>> x, y, z = z, x, y

>>> x
'abc'

>>> y
1

>>> z
2


三、标识符

       标识符是计算机语言中允许作为名字的有效字符串集合。其中,有一部分是关键字,构成语言的标识符。这样的标识符是保留字,不能用于其他用途。
       Python还有称为“内建”(built-in)的标识符集合,虽然不是保留字,但是不推荐使用。

3.1  合法的Python标识符

第一个字符必须是字母或下划线
剩下的字符可以是字母、数字和下划线
大小写敏感

3.2  关键字
       Keyword模块中同时包含了一个关键字列表和一个iskeyword()函数。
>>> keyword.kwlist    #python2.7.11
['and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'exec', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'not', 'or', 'pass', 'print', 'raise', 'return', 'try', 'while', 'with', 'yield']


3.3  内建
       Python还有可以在任何一级代码使用的“内建”的名字集合,这些名字可以由解释器设置或使用。建议将其当做“系统保留字”。
       然而,有些情况需要重定义、替换它们。
       built-in是__builtins__模块的成员,在程序开始或在交互式解释器给出 >>> 提示之前,由解释器自动导入。把它们看成适用在任何一级Python代码的全局变量。

3.4  专用下划线标识符

_xxx    不用from module import *  导入
_xxx_   系统定义名字
_xxx     类中的私有变量名

核心风格:避免用下划线作为变量名的开始。一般来讲,变量名_xxx 被看做是私有的,在模块或类外不可用适用。当变量是私有的时候,用_xxx来表示变量是很好的习惯。
d284

四、基本风格指南

注释
文档,Python可以通过__doc__ 特别变量,动态获得文档字符串。
缩进
选择标识符名称

4.1  模块结构和布局

1、 起始行
      通常只在Unix环境下才使用起始行。可以仅输入脚本名称来执行脚本。

2、 模块文档
      简单介绍模块的功能及重要全局变量的含义

3、 模块导入
      导入当前模块的代码需要的所有模块;每个模块仅导入一次。函数内部的模块导入代码不会被执行,除非该函数正在执行。

4、 变量定义
      这里定义的变量为全局变量,本模块中的所有函数都可直接使用。但是,尽量使用局部变量来代替全局变量,可以提高性能并节省内存。

5、 类定义语句
      所有的类都需要在这里定义。当模块被导入时class语句会被执行,类也就会被定义。

6、 函数定义语句
      此处定义的函数可以通过module.function()在外部被访问到,当模块被导入时 def 语句会被执行,函数也就都会定义好。

7、 主程序
      无论这个模块是被别的模块导入还是作为脚本直接执行,都会执行这部分代码。通常这里不会有太多功能性代码,二十根据执行的模式调用不同的函数。

核心风格:主程序调用main()函数
       主程序检查 __name__ 变量的值然后执行相应的调用。主程序中的代码通常包括变量赋值、类定义和函数定义,随后检查 __name__ 来决定是否调用另一个函数(通常是main()函数)来完成该模块的功能。 这儿是放置测试代码的好地方。大部分的Python模块都是用于导入调用的,直接运行模块应该调用该模块的回归测试代码。

      很多项目都是一个主程序,由它导入所需要的模块。总之,只有一个模块,也就是包含主程序的模块会被直接执行,或由用户通过命令、或作为批处理、或Unix cron 定时执行、或web服务器调用、或通过GUI执行。

核心笔记: __name__ 指示模块应该如何被加载
        由于主程序代码无论模块是被导入还是被直接执行都会运行,我们必须知道模块如何决定运行方向。一个应用程序可能需要导入另一个应用程序的一个模块,以便重用一些有用的代码。这种情况下,只想访问那些位于其他应用程序的代码而不想运行那个应用程序。通过 __name__ 系统变量来判断该模块是被导入还是直接执行。
        如果是被导入: __name__  的值是模块名称
        如果是直接执行, __name__ 的值是 '__main__'

4.2  在主程序中书写测试代码

       测试代码仅当该文件被直接执行时运行。利用 __name__ 变量将测试代码放在一个叫做main()或 test()的函数中,如果该模块被当成脚本运行,则调用这个函数。
       这些测试代码应该随着测试条件和测试结果的变更及时修改,,每次代码更新,都应该运行这些测试代码。

五、内存管理

变量无须事先声明
变量无须指定类型
程序员不必关心内存管理
变量名会被“回收”
del  语句能直接释放资源

5.1  变量定义

       Python中无须显示的变量声明语句,变量在第一次被赋值时自动声明。变量只有在被创建和赋值后才能被引用
       
>>> a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
name 'a' is not defined

>>> a = 'abcdasdf'

>>> a
'abcdasdf'


5.2  动态类型

       Python也无须声明变量类型,对象的类型和内存占用都是运行时确定的。在赋值时,解释器会根据语法和右侧的操作数来决定新对象的类型。在对象创建后,一个该对象的应用会被赋值给左侧的变量。

5.3  内存分配

       Python解释器承担了内存管理的复杂任务。

5.4  引用计数

       要保持追踪内存种的对象,Python使用了引用计数这一技术。也就是说Python内部记录着所有使用对象各有多少引用。一个内部跟踪变量,称为一个引用计数器。每个对象各有多少引用,简称引用计数。当对象被创建时,就创建了一个引用计数,当这个对象不再需要,也可以说当对象的引用计数变为0时,它被垃圾回收。

5.4.1 增加引用计数

          当对象被创建并赋值给变量时,该对象的引用计数就被设置为1.
          当同一个对象(的引用)又被赋值给其他变量,或作为参数传递给函数、方法或类实例时,或者被赋值为一个窗口对象的成员时,该对象的一个新的引用或称作别名就被创建,此时引用计数自动加1.
          
>>> x = 3

>>> y = x


5.4.2 减少引用计数

         当对象的引用被销毁时,引用计数会减小。最明显的例子就是当引用离开其作用范围时,这种情况一般出现在函数运行结束时,所有局部变量被自动销毁。
          
>>> s1 = 'xyz'

>>> s2 = s1

>>> s2 = 'abc'
 
s1的引用计数从1变成2再变成1.

总结,引用计数减少的情况

一个本地引用离开了其作用范围
对象被显示销毁       del  y
对象的一个别名被赋值给其他对象    x = 123
对象被从一个窗口对象中移除   list1.remove(x)
窗口对象本身被销毁   del  list1

5.4.3  del语句

          del语句会删除对象的一个引用。 del y  在上例中会导致:从现在的名称空间中删除y, x  的引用计数减1 
             del x  会删除该对象的最后一个引用。这会导致该对象从此无法访问。从此刻起,该对象就成为垃圾回收机制的回收对象。注意任何追踪或调试程序会给一个对象增加一个额外的引用,这会推迟该对象被回收的时间。

5.5  垃圾回收

       垃圾收集器是一块独立的代码,用来寻找引用计数为0的对象。它也负责检查那些虽然引用计数大于0但是应该被销毁的对象。
       一个循环引用发生在当有至少两个对象相互引用时。Python的垃圾收集器实际上是一个引用计数器和一个循环垃圾收集器。

六、第一个Python程序

1 #!/usr/bin/python
2 # -*- coding:utf-8 -*-
3
4 '''
5 makeTextFile.py  ----  create text file
6 '''
7
8 import os
9 ls = os.linesep
10
11 #get filename
12 while True:
13
14     if os.path.exists(fname):
15         print "Error: '%s' already exists" % fname
16     else:
17         break
18
19 #get file content (text) lines
20 all = []
21 print "\nEnter lines ('.' by itself to quit).\n"
22
23 #loop until user terminates input
24 while True:
25     entry = raw_input('>')
26     if entry == '.':
27         break
28     else:
29         all.append(entry)
30
31 #write lines to file with proper line-ending
32 fobj = open(fname,'w')
33 fobj.writelines(['%s%s' % (x, ls) for x in all])
34 fobj.close()
35 print "Done"


核心提示:使用局部变量替换模块变量
       类似os.linesep这样的名字需要解释器做两次查询。如果在一个函数中频繁的使用一个属性,建议为该属性取一个本地变量别名。

readTextFile.py
1 #!/usr/bin/python
2 # -*- coding:utf-8 -*-
3
4 '''
5 readTextFile.py ----  read and display text file.
6 '''
7
8 #get filename
9 fname = raw_input("Enter filename: \n")
10 print
11
12 #attempt to open file for reading
13 try:
14     fobj = open(fname,'r')
15 except IOError,e:
16     print "*** file open error:", e
17 else:
18     #display content to the screen
19     for eachLine in fobj:
20         print eachLine,
21     fobj.close()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  python