《Python核心编程》第三章:Python基础

PS:【笔记+代码+图片】在GitHub上持续更新,欢迎star:https://github.com/gdouchufu/Core-Python-Programming


1.本章大纲

介绍基本的语法、编码风格、内存管理机制,以一个读写文件的Python程序拉开Python编程的序幕。


2.知识点

2.1语句和语法

  • Python 使用缩进来分隔代码组,代码的层次关系通过同样深度的空格或制表符缩进体现。同一代码组的代码行必须严格左对齐(左边有同样多的空格或同样多的制表符)。

  • Python 的赋值语句不会返回值。

2.2变量赋值

  • 同时给多个变量赋值(类似元组):go_surf, get_a_tan_while, boat_size, toll_money = (1,'windsurfing', 40.0, -2.00) 

  • 交换两个值:x, y = y, x

2.3标识符和关键字

  • __xxx__:系统定义的名字(__doc__ | __class__ | __name__ | ...)

  • __xxx:类中的私有变量名

2.4基本风格指南

  • 在 Python 解释器输入 import this 然后回车可以查看“Pythonic”【以 Python 的方式去编写代码、组织逻辑,及对象行为】

  • 尽量使用局部变量代替全局变量,好处:易维护、提高性能、节省内存。(在查找全局变量之前,总是先查找本地变量!

2.5内存管理

  • Python是一种解释型语言,对象的类型和内存占用都是运行时确定的,在赋值时解释器会根据语法和右侧的操作数来决定新对象的类型。

  • Python 内部记录着所有使用中的对象各有多少引用,一个内部跟踪变量称为一个引用计数器。每个对象各有多少个引用,简称引用计数。当对象被创建时, 就创建了一个引用计数, 当这个对象不再需要时(这个对象的引用计数变为0时),它被垃圾回收。

  • Python 的垃圾收集器实际上是一个引用计数器和一个循环垃圾收集器。 当一个对象的引用计数变为 0,解释器会释放掉这个对象和仅有这个对象可访问(可到达)的其它对象。作为引用计数的补充, 垃圾收集器也会留心被分配的总量很大(及未通过引用计数销毁的那些)的对象。 在这种情况下, 解释器会暂停下来,试图清理所有未引用的循环。

  • del obj删除对象的最后一个引用, 也就是该对象的引用计数会减为0,使该对象就成为垃圾回收机制的回收对象。(注意:任何追踪或调试程序会给一个对象增加一个额外的引用, 这会推迟该对象被回收的时间。)

2.6第一个 Python 程序

  • 简洁的写法:fobj.writelines(['%s %s' % (x, ls) for x in all])

2.7常用模块

  • PyUnit(测试模块):unittest。

  • Debugger(调试模块): pdb,支持断点,代码逐行执行,检查堆栈。它还支持事后调试

  • Logger(日志模块): logging,定义了一些函数和类帮助你的程序实现灵活的日志系统。

  • Profilers(性能测试模块): profile, hotshot, cProfile


3.练习

3–1. 标识符。为什么 Python 中不需要变量名和变量类型声明?

变量名的作用是指向一个对象,单纯只创建对象而没有变量指向它是允许的;

Python是动态语言,在运行时根据语法和右侧的操作数来决定对象的类型,所以不需要申明变量类型


【补充】

动态语言和静态语言的区别:

动态、静态是指变量的绑定方式,静态语言在编译时绑定,动态语言可以在运行时随意绑定。

Java是静态语言,一个变量定义好了数据类型就不能再改变。如:定义了 String str = 'hello' 后,str = 123就不行;

Python是动态语言,在运行时根据语法和右侧的操作数来决定对象的类型。如:str = 'hello',重新赋值 str = 123 是可以的。


强类型和弱类型:

类型、弱类型是指变量的类型在运算上下文中是否可以自动转换。

对于 1 + "1000" 这样一条语句:

Python会报错,因为它是强类型语言,不能将"1000"自动转换成1000,再和1相加;

而Perl便能进行自动类型转换,所以它是弱类型。


3–2. 标识符。为什么 Python 中不需要声明函数类型?

还是跟python是动态语言有关,在运行时根据返回类型决定函数类型,如果函数没有显式地return一个函数类型的话,那么函数类型是NoneType


3–3. 标识符。为什么应当避免在变量名的开始和和结尾使用双下划线?

因为类似__xxx__的变量名是系统定义的名字,容易发生冲突。


3–4. 语句。在 Python 中一行可以书写多个语句吗?

可以,用分号 ; 


3–5. 语句。在 Python 中可以将一个语句分成多行书写吗?

可以,用反斜杠 \


3–6. 变量赋值

(a)赋值语句 x, y, z = 1, 2, 3 会在 x、y、z 中分别赋什么值?

x=1, y=2, z=3

(b)执行 z, x, y = y, z, x 后,x、y、z 中分别含有什么值?

x=3, y=1, z=2


3–7. 标识符。下面哪些是 Python 合法的标识符?如果不是,请说明理由!在合法的标识符中,哪些是关键字?

int32(合法标识符)

40XL(非法标识符 - 以数字开头)

$aving$(非法标识符 - 以$开头)

printf(合法标识符)

print(关键字)

_print(合法标识符)

this(关键字)

self(关键字)

__name__

0x40L(非法标识符 - 以数字开头)

bool(合法标识符)

true(合法标识符)

big-daddy(合法标识符)

2hot2touch(非法标识符 - 以数字开头)

type(关键字)

thisIsn'tAVar(非法标识符 - 含有')

thisIsAVar(合法标识符)

R_U_Ready(合法标识符)

Int(合法标识符)

True(关键字)

if(关键字)

do(关键字)

counter-1(合法标识符)

access(合法标识符)

_(合法标识符)


3–8. Python 代码。将脚本拷贝到您的文件系统中,然后修改它。可以添加注释,修改提示符(‘>’太单调了)等等,修改这些代码,使它看上去更舒服。

get


3–9. 移植。 如果你在不同类型的计算机系统中分别安装有 Python, 检查一下,os.linesep 的值是否有不同。 记下操作系统的类型以及 linesep 的值。

Linux_x64操作系统'\n'

Windows_x64操作系统'\r\n'


3–10. 异常。使用类似 readTextFile.py 中异常处理的方法取代makeTextFile.py 中 对 os.path.exists() 的 调 用 。 反 过 来 , 用 os.path.exists() 取 代readTextFile.py 中的异常处理方法。

makeTextFile.py:

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

readTextFile.py:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/usr/bin/env python
import  os
'readTextFile.py -- read and display text file'
 
# get filename
fname  =  raw_input ( 'Enter filename: ' )
print
 
# attempt to open file for reading
if  not  os.path.exists(fname):
     print  "ERROR: '%s' not exists"  %  fname
else :
     fobj  =  open (fname,  'r' )
     # display contents to the screen
     for  eachLine  in  fobj:
         print  eachLine,
     fobj.close()
 
    


3–11.字符串格式化 不再抑制 readTextFile.py 中 print 语句生成的 NEWLINE 字符, 修改你的代码, 在显示一行之前删除每行末尾的空白。 这样, 你就可以移除 print 语句末尾的逗号了。

eachLine.strip()


3–12. 合并源文件。将两段程序合并成一个,给它起一个你喜欢的名字,比方readNwriteTextFiles.py。让用户自己选择是创建还是显示一个文本文件。

readNwriteTextFile.py:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#!/usr/bin/env python
 
import  os
ls  =  os.linesep
 
def  readFile():
     # get filename
     fname  =  raw_input ( 'Enter filename: ' )
     print
 
     # attempt to open file for reading
     try :
         fobj  =  open (fname,  'r' )
     except  IOError, e:
         print  "*** file open error:" , e
     else :
         # display contents to the screen
         for  eachLine  in  fobj:
             print  eachLine,
         fobj.close()
 
def  writeFile():
     # get filename
     while  True :
         fname  =  raw_input ( 'Enter filename: ' )
         print
 
         if  os.path.exists(fname):
            print  "ERROR: '%s' already exists"  %  fname
         else :
            break
 
     # get file content (text) lines
     all  =  []
     print  "\nEnter lines ('.' by itself to quit).\n"
 
     # loop until user terminates input
     while  True :
         entry  =  raw_input ( '$ ' )
         if  entry  = =  '.' :
             break
         else :
             all .append(entry)
 
     # write lines to file with proper line-ending
     fobj  =  open (fname,  'w' )
     fobj.writelines([ '%s%s'  %  (x, ls)  for  in  all ])
     fobj.close()
 
while  True :
     choose  =  raw_input ( 'choose action: r | w :' )
     if  (choose  = =  'r' ):
         readFile()
         break
     elif  (choose  = =  'w' ):
         writeFile()
         break


3–13. 添加新功能。 将你上一个问题改造好的 readNwriteTextFiles.py 增加一个新功能:允许用户编辑一个已经存在的文本文件。 你可以使用任何方式,无论是一次编辑一行,还是一次编辑所有文本。需要提醒一下的是, 一次编辑全部文本有一定难度, 你可能需要借助 GUI工具包或一个基于屏幕文本编辑的模块比如 curses 模块。要允许用户保存他的修改(保存到文件)或取消他的修改(不改变原始文件),并且要确保原始文件的安全性(不论程序是否正常关闭)。

editTextFile.py:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#!/usr/bin/env python
import  os
 
print  "************ Text File Editor ************"
print
 
line_sum  =  0 ;
all_content  =  []
 
# get filename
while  True :
     try :
         fname  =  raw_input ( '>>> enter filename: ' )
         fobj  =  open (fname,  'r' )
         break
     except  IOError, e:
         print  '>>> [ERROR] file open failed:' , e
 
# get original content
for  line  in  fobj.readlines():   
     all_content.append(line)
     print  line,
     line_sum  + =  1
 
def  get_new_content():
     while  True :
         choose_line_num  =  raw_input ( '>>> select one line to edit [1-%d] : '  %  line_sum)
         try :
             choose_line_num  =  int (choose_line_num)
             if  not  ( 0  < choose_line_num < =  line_sum):
                 print  '>>> [ERROR] the line number must in [1-%d] !'  %  line_sum
                 continue
             break
         except  ValueError, e:
             print  '>>> [ERROR] number transform failed: ' , e
 
     print  '>>> your choose line is : %d'  %  choose_line_num
     new_content  =  raw_input ( '>>> input new content: ' )
     all_content[choose_line_num - 1 =  new_content  +  os.linesep
 
# generate new content
if  line_sum >  0 :
     get_new_content()
else :
     print  '>>> the file is empty, please input new content directly:'
     new_content  =  raw_input ( '>>> ' )
     all_content.append(new_content)
 
# save new content
fobj  =  open (fname,  'w' )
for  line  in  all_content:
     fobj.write(line)
fobj.close()
print  '>>> save success, bye!'
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值