语句和语法
变量赋值
标识符和关键字
基本风格指南
内存管理
第一个 Python 程序
Python 语句中有一些基本规则和特殊字符:
-
井号(#)表示之后的字符为 Python 注释
-
换行 (\n) 是标准的行分隔符(通常一个语句一行)
-
反斜线 ( \ ) 继续上一行(闭合操作符时,单一语句可以 跨多行,例如:在含有小括号、中括号、花括号时可以多行书写。另外就是三引号包括下的字符串也可以跨行书写 )
-
分号 ( ; )将两个语句连接在一行中 import sys; x = 'foo'; sys.stdout.write(x + '\n')
-
冒号 ( : ) 将代码块的头和体分开
-
语句(代码块)用缩进块的方式体现
-
不同的缩进深度分隔不同的代码块 --不要使用 Tab
-
Python文件以模块的形式组织
Python.py 文件=XXX模块
XX模块内是直接运行的代码块/类定义/函数定义/以上组合
路径--文件/模块--类/函数--方法
python语言,将该对象的引用(并不是值)赋值给变量;支持增量赋值运算符 += -= *= /= %= **= <<= >>= &= ^= |=;不支持类似 x++ 或 --x 这样的前置/后置自增/自减运算;支持连续赋值
x=y=z=3
print(x,y,z)
多个变量同时赋值的方法 ,默认按元组处理:
(x,y,z)=(1,2,'string')
print (x,y,z)
变量 x 和变量 y 的值被互相交换:
(x,y,z)=(1,2,'string')
print (x,y)
x,z = z,x
print(x,y)
标识符是电脑语言中允许作为名字的有效字符串集合.包括 关键字、built-in标识符集合。合法标识符 :
第一个字符必须是字母或下划线(_)
剩下的字符可以是字母和数字或下划线
大小写敏感
关键字列表和 iskeyword()函数都放入了 keyword 模块以便查阅
Python 用下划线作为变量前缀和后缀指定特殊变量:
_xxx 不用'from module import *'导入 ------“私有的”,在模块或类外不可以使用
__xxx__系统定义名字----__doc__特别变量,动态获得文档字串,obj.__doc__来进行访问,其中 obj 是一个模块,类,或函数的名字
__xxx 类中的私有变量名
模块结构和布局
# (1) 起始行(Unix) 有起始行就能够仅输入脚本名字来执行脚本,无 需直接调用解释器
# (2) 模块文档 模块外可通过 module.__doc__ 访问
# (3) 模块导入 每个模块仅导入一次(当前模块被加载时);函数内部的模块导入代码不会被执行, 除非该函数正在执行
# (4) 变量定义 尽量使用局部变量代替全局变量
# (5) 类定义 class.__doc__ 当模块被导入时 class 语句会被执行, 类也就会被定义
# (6) 函数定义 module.function()在外部被访问到,当模块被导入时 def 语句 会被执行, 函数也就都会定义好,函数的文档变量是 function.__doc__
# (7) 主程序
通常只有主程序模块中有大量的顶级可执行代码, 所有其它被导入的模块只应该有很少的顶级执行代码,所有的功能代码都应该封装在函数或类 当中。
如果模块是被导入, __name__ 的值为模块名字
如果模块是被直接执行, __name__ 的值为 '__main__'
Python 解释器承担了内存管理的复杂任务。
当对象被创建并(将其引用)赋值给变量时,该对象的引用计数就被设置为 1。
【对象的引用计数在以下情况下+1】
对象被创建 x = 3.14;
或另外的别名被创建 y= x;
或被作为参数传递给函数(新的本地引用) foobar(x);
或成为容器对象的一个元素 myList = [123, x, 'xyz']
foo = 'xyz'
bar = foo
foo = 123
当字符串对象"xyz"被创建并赋值给 foo 时, 它的引用计数是 1. 当增加了一个别名 bar 时, 引用计数变成了 2. 不过当 foo 被重新赋值给整数对象 123 时, xyz 对象的引用计数自动减 1,又重新变成了 1.
【一个对象的引用计数在以下情况会减少】
一个本地引用离开了其作用范围。比如 foobar()函数结束时。 对象的别名被显式的销毁。del y # or del x
对象的一个别名被赋值给其它的对象 x = 123
对象被从一个窗口对象中移除 myList.remove(x)
窗口对象本身被销毁 del myList # or goes out-of-scope
3.8 练习
-
3–1. 标识符。为什么 Python 中不需要变量名+变量类型 形式的声明? -------Python 是动态类型语言,在赋值时,根据"=" 右边动态确定变量类型,不需要特别的声明,在运行时,才会调用类型使用。变量在第一次被赋值时自动声明。Python 语言中, 对象的类型和内存占用都是运行时确定的。尽管代码被编译成字节码,Python 仍然是一种解释型语言。
-
3–2. 标识符。为什么 Python 中不需要声明函数类型?-------函数没有定义返回的数据类型。 Python不需要提定返回值的数据类型;甚至不需要指定是否有返回值。实际上,每个Python函数都返回一个值;如果函数执行过return语句,它将返回指定的值,否则将返回None(Python 的空值)。
-
3–3. 标识符。为什么应当避免在变量名的开始和和结尾使用双下划线?--------_xxxx__ 这样的变量类型在python中有特殊意义,表示 "系统定义名字" ,这样的做的目的减少自定义变量覆盖系统定义变量,从而导致脚本运行出错。
-
3–4. 语句。在 Python 中一行可以书写多个语句吗?---可以,;隔开
-
3–5. 语句。在Python中可以将一个语句分成多行书写吗? 可以,\ 分多行书写
-
3–6. 变量赋值
(a)赋值语句 x, y, z = 1, 2, 3 会在 x、y、z 中分别赋什么值? ------x 1、y2、z3
(b)执行 z, x, y = y, z, x 后,x、y、z 中分别含有什么值? ---x3、y1、z2
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 -
----合法标识符:字母/下划线开头、后跟字母/数字/下划线、大小写敏感
int32 printf print _print this self __name__ bool true type thisIsAVar R_U_Ready Int True if do access
----即是合法标识符又是关键字:print if
关键字列表
下面的问题涉及了 makeTextFile.py 和 readTextFile.py 脚本。
3–8. Python 代码。将脚本拷贝到您的文件系统中,然后修改它。可以添加注释,修改 提示符(‘>’太单调了)等等,修改这些代码,使它看上去更舒服。
【MakeTextFile.py】
#!/usr/bin/env python
'makeTextFile.py --create text file'
import os
# os.linesep字符串给出当前平台使用的行终止符。例如,Windows使用’\r\n’,Linux使用’\n’而Mac使用’\r’
ls = os.linesep
# get filename, 判断一个文件是否存在,比如 os.path.exists('d:/assist/getTeacherList.py')
while True:
fname = input('please enter a filename: ')
if os.path.exists(fname):
print("Error: %s already exists! " % (fname))
else:
break
# get file content (text) lines。all() 函数用于判断给定的可迭代参数 iterable 中的所有元素是否都为 TRUE,如果是返回 True,否则返回 False。
alls = []
print("\nEnter lines('.' by itself to quit)\n")
# loop until user terminates input
while True:
entry = input('>请输入你的文本:')
if entry == '.':
break
else:
alls.append(entry)
# append() 方法用于在列表末尾添加新的对象
# write lines to file with proper line-ending
# python open() 函数用于打开一个文件,创建一个 file 对象,相关的方法才可以调用它进行读写;
# file.writelines(sequence)的参数是序列,比如列表,它会迭代帮你写入文件;file.write(str)的参数是一个字符串,就是你要写入文件的内容.
fobj = open(fname, 'w')
fobj.writelines(['%s %s' % (x, ls) for x in alls])
fobj.close()
print('Done')
【readTextFile.py】
#!/usr/bin/env Python
'readTextFile.py --read and display text file'
#get file name
fname = input('Enter filename:')
print
#attemp to open file for reading
try:
fobj = open(fname,'r')
#except:<异常名>,<数据>:捕获指定异常及其附加的数据;
#异常名 描述
#AttributeError 调用不存在的方法引发的异常
#EOFError 遇到文件末尾引发的异常
#ImportError 导入模块出错引发的异常
#IndexError 列表越界引发的异常
#IOError I/O操作引发的异常,如打开文件出错等
#KeyError 使用字典中不存在的关键字引发的异常
#NameError 使用不存在的变量名引发的异常
#TabError 语句块缩进不正确引发的异常
#ValueError 搜索列表中不存在的值引发的异常
#ZeroDivisionError 除数为零引发的异常
except IOError as e:
print ("**file open error:", e)
else:
#display contents to the screen
for eachLine in fobj:
print (eachLine),
fobj.close()
3–9. 移植。 如果你在不同类型的计算机系统中分别安装有 Python, 检查一下, os.linesep 的值是否有不同。 记下操作系统的类型以及 linesep 的值。
>>> os.linesep
'\n'
3–10. 异常。使用类似 readTextFile.py 中异常处理的方法取代 readTextFile.py makeTextFile.py 中对 os.path.exists()的调用。反过来, 用 os.path.exists()取代 readTextFile.py 中的异常处理方法。
[readTextFile.py]
#fobj = open(fname, 'r')
#if (os.path.exists(fname)):
# display contents to the screen
for eachLine in fobj:
print(eachLine),
fobj.close()
#print('there is no this file')
3–11.
字符串格式化不再抑制 readTextFile.py 中 print 语句生成的 NEWLINE 字符,修改你的代码,在显示一行之前删除每行末尾的空白。这样,你就可以移除 print语句末尾的逗号了。 提示: 使用字符串对象的 strip()方法
for eachLine in fobj:
#print(eachLine),
print(eachLine.strip())
3–12. 合并源文件。将两段程序合并成一个,给它起一个你喜欢的名字,比方 readNwriteTextFiles.py。让用户自己选择是创建还是显示一个文本文件。
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import os
ls=os.linesep
#'''
def Write_file():
#'makeTextFile.py -- create text file'
# get filename
while True:
fname = input('enter a file name')
if os.path.exists(fname):
print ("ERROR: '%s' already exists" % fname)
else:
break
# get file content lines
all = []
print ("\nEnter lines ('.' by itself to quit).\n")
# loop until user terminates input
while True:
entry = 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()
print ('DONE!')
def READ_FILE():
# 'readTextFile.py -- read and display text file'
# get filename
fname = input('Enter filename: ')
print
# attempt to open file for reading
try:
fobj = open(fname, 'r')
except IOError as e:
print ("*** file open error:" , e)
else:
# display contents to the screen
for eachLine in fobj:
#print eachLine,
print(eachLine.strip())
fobj.close()
if __name__=="__main__":
while True:
print
"""please select target:
1) read txtfile
2) create a textfile
3) quit
"""
getcode = input("which one: ")
if getcode == '1':
READ_FILE()
elif getcode == '2':
Write_file()
elif getcode == '3':
break
else:
print("check you choice,repeat")
3–13. 添加新功能。将你上一个问题改造好的 readNwriteTextFiles.py 增加一个新功 能:允许用户编辑一个已经存在的文本文件。 你可以使用任何方式,无论是一次编辑一行,还 是一次编辑所有文本。需要提醒一下的是,一次编辑全部文本有一定难度,你可能需要借助 GUI 工具包或一个基于屏幕文本编辑的模块比如 curses 模块。要允许用户保存他的修改(保存到 文件)或取消他的修改(不改变原始文件),并且要确保原始文件的安全性(不论程序是否正 常关闭)。(看不懂,先留着后面再学)
#!/usr/bin/env python
#-*- coding: utf-8 -*-
from Tkinter import * #Tkinter 是 Python 的标准 GUI 库
import tkMessageBox,tkFileDialog
import platform
# nl = os.linesep
def openfile():
global filename # 使用global声明为全局变量,方便后边的程序调用
systype = platform.system() # 判断系统类型
if systype == 'windows':
basedir = 'c:\\'
else:
basedir = '/'
filename = tkFileDialog.askopenfilename(initialdir=basedir)
try:
fobj_r = open(filename, 'r')
except IOError as errmsg:
print ('*** Failed open file:', errmsg)
else:
editbox.delete(1.0, END)
for eachline in fobj_r:
editbox.insert(INSERT, eachline)
fobj_r.close()
def savefile():
save_data = editbox.get(1.0, END)
try:
fobj_w = open(filename, 'w')
fobj_w.writelines(save_data.encode('utf-8'))
fobj_w.close()
tkMessageBox.showinfo(title='提示',
message='保存成功')
except IOError, errmsg:
tkMessageBox.showwarning(title='保存失败', message='保存出错')
tkMessageBox.showwarning(title='错误信息', message=errmsg)
except NameError:
tkMessageBox.showwarning(title='保存失败', message='未打开文件')
def showlinenum():
tkMessageBox.showinfo(title='提示',
message='这个功能作者现在不会写,放这里装饰用的.')
def destroy_ui(ui):
ui.destroy()
def aboutauthor():
author_ui = Toplevel()
author_ui.title('关于')
author_ui.geometry('200x80')
about_string = Label(author_ui,
text="作者: ToughGuy\n\n主页: http://www.techzhai.net/")
confirmbtn = Button(author_ui, text='确定',
command=lambda:destroy_ui(author_ui))
about_string.pack()
confirmbtn.pack()
# author_ui.mainloop()
def CreateMenus():
# 初始化菜单
Menubar = Menu(root)
# 创建文件菜单
filemenu = Menu(Menubar, tearoff=0)
filemenu.add_command(label='打开文件', command=openfile)
filemenu.add_command(label='保存文件', command=savefile)
filemenu.add_command(label='退出', command=lambda:destroy_ui(root))
Menubar.add_cascade(label='文件', menu=filemenu)
# 创建编辑菜单
editmenu = Menu(Menubar, tearoff=0)
editmenu.add_command(label='显示行号', command=showlinenum)
Menubar.add_cascade(label='编辑', menu=editmenu)
# 创建帮助菜单
helpmenu = Menu(Menubar, tearoff=0)
helpmenu.add_command(label='关于作者', command=aboutauthor)
Menubar.add_cascade(label='帮助', menu=helpmenu)
root.config(menu=Menubar)
root = Tk()
root.title('文本编辑器')
root.geometry('500x400')
CreateMenus()
editbox = Text(root, width=70, height=25, bg='white')
editbox.pack(side=TOP, fill=X)
root.mainloop()