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

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


本章大纲

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

知识点

3.1 语句和语法

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

3.2 变量赋值

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

3.3 标识符和关键字

  • __xxx__:系统定义的名字(__doc__ | __class__ | __name__ | …)
  • __xxx:类中的私有变量名

3.4 基本风格指南

  • 在 Python 解释器输入 import this 然后回车可以查看“Pythonic”【以 Python 的方式去编写代码、组织逻辑,及对象行为】
  • 尽量使用局部变量代替全局变量,好处:易维护、提高性能、节省内存。(在查找全局变量之前,总是先查找本地变量!

3.5 内存管理

  • Python是一种解释型语言,对象的类型和内存占用都是运行时确定的,在赋值时解释器会根据语法和右侧的操作数来决定新对象的类型。
  • Python 内部记录着所有使用中的对象各有多少引用,一个内部跟踪变量称为一个引用计数器。每个对象各有多少个引用,简称引用计数。当对象被创建时, 就创建了一个引用计数, 当这个对象不再需要时(这个对象的引用计数变为0时),它被垃圾回收。
  • Python 的垃圾收集器实际上是一个引用计数器和一个循环垃圾收集器。 当一个对象的引用计数变为 0,解释器会释放掉这个对象和仅有这个对象可访问(可到达)的其它对象。作为引用计数的补充, 垃圾收集器也会留心被分配的总量很大(及未通过引用计数销毁的那些)的对象。 在这种情况下, 解释器会暂停下来,试图清理所有未引用的循环。
  • del obj:删除对象的最后一个引用, 也就是该对象的引用计数会减为0,使该对象就成为垃圾回收机制的回收对象。(注意:任何追踪或调试程序会给一个对象增加一个额外的引用, 这会推迟该对象被回收的时间。)

3.6 第一个 Python 程序

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

3.7 常用模块

  • PyUnit(测试模块):unittest
  • Debugger(调试模块): pdb,支持断点,代码逐行执行,检查堆栈。它还支持事后调试
  • Logger(日志模块): logging,定义了一些函数和类帮助你的程序实现灵活的日志系统。
  • Profilers(性能测试模块): profile, hotshot, cProfile

练习

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 合法的标识符?如果不是,请说明理由!在合法的标识符中,哪些是关键字?
1. int32 (合法标识符)
2. 40XL (非法标识符 - 以数字开头)
3. $aving$ (非法标识符 - 以$开头)
4. printf (合法标识符)
5. print (关键字)
6. _print (合法标识符)
7. this (关键字)
8. self (关键字)
9. __name__ (合法标识符)
10. 0x40L (非法标识符 - 以数字开头)
11. bool (合法标识符)
12. true (合法标识符)
13. big-daddy (合法标识符)
14. 2hot2touch (非法标识符 - 以数字开头)
15. type (关键字)
16. thisIsn'tAVar (非法标识符 - 含有’)
17. thisIsAVar (合法标识符)
18. R_U_Ready (合法标识符)
19. Int (合法标识符)
20. True (关键字)
21. if (关键字)
22. do (关键字)
23. counter-1 (合法标识符)
24. access (合法标识符)
25. _ (合法标识符)

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

略。

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:

#!/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 x in all])
    fobj.close()

readTextFile.py:

#!/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。让用户自己选择是创建还是显示一个文本文件。

#!/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 x 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 模块。要允许用户保存他的修改(保存到文件)或取消他的修改(不改变原始文件),并且要确保原始文件的安全性(不论程序是否正*常关闭)。*

#!/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!'
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值