最近在学习python,把学习的过程记录下来,方便以后查看
1. 学习资料
菜鸟教程
Python官网
Python论坛
廖学峰的官方网站
2. 开发环境
因为在mac上做开发,系统自带了2.7的python版本。官网目前python最新版本为3.6.
2.x和3.x语法上有不同,既然刚开始学习,果断入手3.6版本。
安装完成后,现在系统中有两个版本的python了。因此修改一下环境变量,在命令行中输入vim ~/.bash_profile
在其中输入以下两行
alias p3="python3"
alias p2="python2"
保存退出,这样在命令行中就可以输入p2或者p3来打开不同版本了
关于IDE的选择,菜鸟教程上也介绍了几种,最受推崇的应该是PyCharm了.但因为是收费版本,而且费用不菲。自己也确实懒得去找破解版了,所以使用SublimeText3。
SublimeText是可以安装插件的,然后将其打造成一个Python的开发利器。插件的事情以后再研究了。
3.Pip包管理工具
安装python时会自动安装pip
可以输入以下命令查看pip版本
pip3 --version
使用方法
pip3 list --outdated
查看哪些包需要更新
pip3 install demjson
安装软件包
pip3 install --upgrade SomePackage
升级软件包
pip3 uninstall SomePackage
卸载软件包
pip3 search SomePackage
查找软件包
pip3 show demjson
查看软件包详情
pip3 list
列出软件包清单
4. 语法
第一个程序
#!/usr/local/bin/python3
#coding=utf-8
print("你好,世界");
在sublime中输入上面三行代码保存。在命令行中进入到文件所在路径。输入
p3 hello.py
即可看到运行结果。
代码说明:
代码第一行表示可执行文件所在路径。因为现在使用的是python3,所以路径为代码中的地址。菜鸟教程中使用的仍是python2.x,因此教程上的路径为#!/usr/bin/python
。此行代码作用是可以在路径下直接用./
来执行文件
在命令行也可通过以下命令查看结果
chmod +x hello.py
./hello.py
代码第二行表示文件编码为utf-8,如果不写的话在显示中文时会报错。
python标识符
- 所有标识符可以包括英文、数字以及下划线(_),但不能以数字开头,区分大小写;
- 以下划线开头的标识符是有特殊意义的。以单下划线开头(_foo)的代表不能直接访问的类属性,需通过类提供的接口进行访问,不能用"from xxx import *"而导入;
- 以双下划线开头的(__foo)代表类的私有成员;
- 以双下划线开头和结尾的(__foo__)代表python里特殊方法专用的标识,如__init__() 代表类的构造函数。
行和缩进
Python的代码块不使用大括号来控制类,而是使用缩进来控制
Python语句中一般以新行作为为语句的结束符。
可以使用斜杠( \)将一行的语句分为多行显示
total = item_one + \
item_two + \
item_three
语句中包含[], {} 或 () 括号就不需要使用多行连接符
days = ['Monday', 'Tuesday', 'Wednesday',
'Thursday', 'Friday']
引号
Python 接收单引号( ' )、双引号( " )、三引号( ''' 或 """ ) 来表示字符串,其中三引号可以由多行组成,编写多行文本的快捷语法
word = 'word'
sentence = "这是一个句子。"
paragraph = """这是一个段落。
包含了多个语句"""
注释
# 第一个注释
'''
这是多行注释,使用单引号。
这是多行注释,使用单引号。
这是多行注释,使用单引号。
'''
"""
这是多行注释,使用双引号。
这是多行注释,使用双引号。
这是多行注释,使用双引号。
"""
等待用户输入
下面的程序在按回车键后就会等待用户输入."\n"在结果输出前会输出一个新的空行。一旦用户按下 enter(回车) 键退出,其它键显示
#!/usr/local/bin/python3
#coding=utf-8
print("你好,世界");
text = input("\nPress the enter key to exit.\n")
print("output:" + text)
数据类型
Python支持以下五中基本数据类型:
- Numbers(数字)
- String(字符串)
- List(列表)
- Tuple(元组)
- Dictionary(字典)
- Set(集合)
字符串
s="1234567890"
可以通过下标来截取字符串 p[头下标:尾下标]
p=s[1:5]
print(p)
//p的结果是 2345
“+”是连字符,“*”是重复符号
#!/usr/local/bin/python3
#coding=utf-8
str = 'Hello World!'
print(str) # 输出完整字符串
print(str[0]) # 输出字符串中的第一个字符
print(str[2:5]) # 输出字符串中第三个至第五个之间的字符串
print(str[2:]) # 输出从第三个字符开始的字符串
print(str * 2) # 输出字符串两次
print(str + "TEST") # 输出连接的字符串
输出结果:
Hello World!
H
llo
llo World!
Hello World!Hello World!
Hello World!TEST
Python列表(List)
#!/usr/local/bin/python3
#coding=utf-8
list = [ 'runoob',786 , 2.23, 'john', 70.2 ]
tinylist = [123, 'john']
print(list) # 输出完整列表
print(list[0]) # 输出列表的第一个元素
print(list[1:3]) # 输出第二个至第三个的元素
print(list[2:]) # 输出从第三个开始至列表末尾的所有元素
print(tinylist * 2) # 输出列表两次
print(list + tinylist) # 打印组合的列表
以上输出结果:
['runoob', 786, 2.23, 'john', 70.2]
runoob
[786, 2.23]
[2.23, 'john', 70.2]
[123, 'john', 123, 'john']
['runoob', 786, 2.23, 'john', 70.2, 123, 'john']
del删除元素
list1 = ['physics', 'chemistry', 1997, 2000];
print(list1)
del list1[2];
print("After deleting value at index 2 : ")
print(list1)
输出结果:
['physics', 'chemistry', 1997, 2000]
After deleting value at index 2 :
['physics', 'chemistry', 2000]
Python元组(Tuple)
元组是另一个数据类型,类似于List(列表)。
元组用"()"标识。内部元素用逗号隔开。但是元组不能二次赋值,相当于只读列表。
#!/usr/local/bin/python3
#coding=utf-8
tuple = ( 'runoob', 786 , 2.23, 'john', 70.2 )
tinytuple = (123, 'john')
print(tuple) # 输出完整元组
print(tuple[0]) # 输出元组的第一个元素
print(tuple[1:3]) # 输出第二个至第三个的元素
print(tuple[2:]) # 输出从第三个开始至列表末尾的所有元素
print(tinytuple * 2) # 输出元组两次
print(tuple + tinytuple) # 打印组合的元组
输出结果:
('runoob', 786, 2.23, 'john', 70.2)
runoob
(786, 2.23)
(2.23, 'john', 70.2)
(123, 'john', 123, 'john')
('runoob', 786, 2.23, 'john', 70.2, 123, 'john')
Python字典(Dictionary)
#!/usr/local/bin/python3
#coding=utf-8
dict = {}
dict['one'] = "This is one"
dict[2] = "This is two"
tinydict = {'name': 'john','code':6734, 'dept': 'sales'}
print(dict['one']) # 输出键为'one' 的值
print(dict[2]) # 输出键为 2 的值
print(tinydict) # 输出完整的字典
print(tinydict.keys()) # 输出所有键
print(tinydict.values()) # 输出所有值
输出结果为:
This is one
This is two
{'name': 'john', 'code': 6734, 'dept': 'sales'}
dict_keys(['name', 'code', 'dept'])
dict_values(['john', 6734, 'sales'])
Python集合(Set)
set和dict类似,也是一组key的集合,但不存储value。由于key不能重复,所以,在set中,没有重复的key
s = set([1, 1, 2, 2, 3, 3])
print(s)
s.add(4)
print(s)
s.add(4)
print(s)
s.remove(4)
print(s)
输出结果:
{1, 2, 3}
{1, 2, 3, 4}
{1, 2, 3, 4}
{1, 2, 3}
Python运算符
运算符 | 描述 | 实例 |
---|---|---|
** | 幂 | 返回x的y次幂 a**b 为10的20次方, 输出结果 100000000000000000000 |
// | 取整除 | 返回商的整数部分 9//2 输出结果 4 , 9.0//2.0 输出结果 4.0 |
and | x and y | 布尔"与" - 如果 x 为 False,x and y 返回 False,否则它返回 y 的计算值。 (a and b) 返回 20。 |
or | x or y | 布尔"或" - 如果 x 是非 0,它返回 x 的值,否则它返回 y 的计算值。 (a or b) 返回 10。 |
not | not x | 布尔"非" - 如果 x 为 True,返回 False 。如果 x 为 False,它返回 True。 not(a and b) 返回 False |
in | 如果在指定的序列中找到值返回 True,否则返回 False。 | x 在 y 序列中 , 如果 x 在 y 序列中返回 True。 |
not in | 如果在指定的序列中没有找到值返回 True,否则返回 False。 | x 不在 y 序列中 , 如果 x 不在 y 序列中返回 True。 |
is | is是判断两个标识符是不是引用自一个对象 | x is y, 如果 id(x) 等于 id(y) , is 返回结果 1 |
is not | is not是判断两个标识符是不是引用自不同对象 | x is not y, 如果 id(x) 不等于 id(y). is not 返回结果 1 |
if语句
#!/usr/local/bin/python3
#coding=utf-8
num = 5
if num == 3: # 判断num的值
print('boss')
elif num == 2:
print('user')
elif num == 1:
print('worker')
elif num < 0: # 值小于零时输出
print('error')
else:
print('roadman') # 条件均不成立时输出
while语句
i = 1
while i < 10:
i += 1
if i%2 > 0: # 非双数时跳过输出
continue
print(i) # 输出双数2、4、6、8、10
i = 1
while 1: # 循环条件为1必定成立
print(i) # 输出1~10
i += 1
if i > 10: # 当i大于10时跳出循环
break
while...else语句和for...else语句
#!/usr/local/bin/python3
#coding=utf-8
count = 0
while count < 5:
print(count, " is less than 5")
count = count + 1
else:
print(count, " is not less than 5")
for循环
for letter in 'Python': # 第一个实例
print('当前字母 :', letter)
fruits = ['banana', 'apple', 'mango']
for fruit in fruits: # 第二个实例
print('当前字母 :', fruit)
print("Good bye!")
通过序列索引迭代
#!/usr/local/bin/python3
#coding=utf-8
fruits = ['banana', 'apple', 'mango']
for index in range(len(fruits)):
print('当前水果 :', fruits[index])
print("Good bye!")
pass语句
pass 不做任何事情,一般用做占位语句。
#!/usr/local/bin/python3
#coding=utf-8
# 输出 Python 的每个字母
for letter in 'Python':
if letter == 'h':
pass
print('这是 pass 块')
print('当前字母 :', letter)
print("Good bye!")
python转义字符
转义字符 | 描述 |
---|---|
\(在行尾时) | 续行符 |
\\ | 反斜杠符号 |
' | 单引号 |
" | 双引号 |
\a | 响铃 |
\b | 退格(Backspace) |
\e | 转义 |
\000 | 空 |
\n | 换行 |
\v | 纵向制表符 |
\t | 横向制表符 |
\r | 回车 |
\f | 换页 |
\oyy | 八进制数,yy代表的字符,例如:\o12代表换行 |
\xyy | 十六进制数,yy代表的字符,例如:\x0a代表换行 |
\other | 其它的字符以普通格式输出 |
Python字符串格式化
print("My name is %s and weight is %d kg!" % ('Zara', 21) )
输出:
My name is Zara and weight is 21 kg!
日期和时间
import time; # 引入time模块
#获取当前时间戳
ticks = time.time()
print("当前时间戳为:", ticks)
#当前时间戳为: 1486715050.71681
#获取当前时间
localtime = time.localtime(time.time())
print("本地时间为 :", localtime)
#本地时间为 : time.struct_time(tm_year=2017, tm_mon=2, tm_mday=10, tm_hour=16, tm_min=24, tm_sec=10, tm_wday=4, tm_yday=41, tm_isdst=0)
#获取格式化的时间
localtime = time.asctime( time.localtime(time.time()) )
print("本地时间为 :", localtime)
#本地时间为 : Fri Feb 10 16:24:10 2017
# 格式化成2016-03-20 11:45:39形式
print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) )
#2017-02-10 16:24:10
# 格式化成Sat Mar 28 22:24:24 2016形式
print(time.strftime("%a %b %d %H:%M:%S %Y", time.localtime()) )
#Fri Feb 10 16:24:10 2017
# 将格式字符串转换为时间戳
a = "Sat Mar 28 22:24:24 2016"
print(time.mktime(time.strptime(a,"%a %b %d %H:%M:%S %Y")))
#1459175064.0
元组时间
很多Python函数用一个元组装起来的9组数字处理时间:
序号 | 字段 | 属性 | 值 |
---|---|---|---|
0 | 4位数年 | tm_year | 2008 |
1 | 月 | tm_mon | 1 到 12 |
2 | 日 | tm_mday | 1到31 |
3 | 小时 | tm_hour | 0到23 |
4 | 分钟 | tm_min | 0到59 |
5 | 秒 | tm_sec | 0到61 (60或61 是闰秒) |
6 | 一周的第几日 | tm_wday | 0到6 (0是周一) |
7 | 一年的第几日 | tm_yday | 1到366 (儒略历) |
8 | 夏令时 | tm_isdst | -1, 0, 1, -1是决定是否为夏令时的旗帜 |
获取日历
import calendar
cal = calendar.month(2017, 2)
print("以下输出2017年2月份的日历:")
print(cal)
输出:
February 2017
Mo Tu We Th Fr Sa Su
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
函数
语法
def functionname( parameters ):
"函数_文档字符串"
function_suite
return [expression]
# 定义函数
def printme( str ):
"打印任何传入的字符串"
print str;
return;
# 调用函数
printme("我要调用用户自定义函数!");
printme("再次调用同一函数");
所有参数(自变量)在Python里都是按引用传递。如果你在函数里修改了参数,那么在调用这个函数的函数里,原始的参数也被改变了
关键字参数
关键字参数使用顺序可以和函数参数声明顺序不一致
#可写函数说明
def printinfo( name, age ):
"打印任何传入的字符串"
print "Name: ", name;
print "Age ", age;
return;
#调用printinfo函数
printinfo("miki",50) #默认参数调用
printinfo( age=50, name="miki" );#关键字参数调用
默认参数
#可写函数说明
def printinfo( name, age = 35 ):
"打印任何传入的字符串"
print "Name: ", name;
print "Age ", age;
return;
#调用printinfo函数
printinfo( age=50, name="miki" );
printinfo( name="miki" );
不定长参数
# 可写函数说明
def printinfo( arg1, *vartuple ):
"打印任何传入的参数"
print "输出: "
print arg1
for var in vartuple:
print var
return;
# 调用printinfo 函数
printinfo( 10 );
printinfo( 70, 60, 50 );
匿名函数
使用lambda
关键字来声明匿名函数
# 可写函数说明
sum = lambda arg1, arg2: arg1 + arg2;
# 调用sum函数
print "相加后的值为 : ", sum( 10, 20 )
print "相加后的值为 : ", sum( 20, 20 )
可变参数
在参数前添加*
,将不变参数变为可变参数
def calc(*numbers):
sum = 0
for n in numbers:
sum = sum + n * n
return sum
print(calc(1, 2)) #输出5
print(calc()) #输出0
nums = [1, 2, 3]
print(calc(nums[0], nums[1], nums[2]))
#或者
print(calc(*nums))
#输出均为14
递归函数
def fact(n):
if n==1:
return 1
return n * fact(n - 1)
当执行fact(1000)
会发生栈溢出。
解决递归调用栈溢出的方法是通过尾递归优化:尾递归是指,在函数返回的时候,调用自身本身,并且,return语句不能包含表达式。这样,编译器或者解释器就可以把尾递归做优化,使递归本身无论调用多少次,都只占用一个栈帧,不会出现栈溢出的情况。
代码修改如下
def fact(n):
return fact_iter(n, 1)
def fact_iter(num, product):
if num == 1:
return product
return fact_iter(num - 1, num * product)
Python 模块
support.py
#!/usr/local/bin/python3
#coding=utf-8
def print_func( par ):
print("Hello : ", par)
return
hello.py
#!/usr/local/bin/python3
#coding=utf-8
# 导入模块
import support
# 现在可以调用模块里包含的函数了
support.print_func("Zara")
定位模块
当导入一个模块,Python对模块位置的搜索顺序是:
- 当前目录
- 如果不在当前目录,Python 则搜索在 shell 变量 PYTHONPATH 下的每个目录。
- 如果都找不到,Python会察看默认路径。UNIX下,默认路径一般为/usr/local/lib/python/。
模块搜索路径存储在system模块的sys.path变量中。变量里包含当前目录,PYTHONPATH和由安装过程决定的默认目录。
作为环境变量,PYTHONPATH由装在一个列表里的许多目录组成。PYTHONPATH的语法和shell变量PATH的一样。
- 在Windows系统,典型的PYTHONPATH如下:
set PYTHONPATH=c:\python20\lib;
- 在UNIX系统,典型的PYTHONPATH如下:
set PYTHONPATH=/usr/local/lib/python
如果要给全局变量在一个函数里赋值,必须使用global语句。
文件内容操作
#!/usr/local/bin/python3
#coding=utf-8
fo = open("foo.txt", "w+")
print("文件名: ", fo.name)
print("是否已关闭 : ", fo.closed)
print("访问模式 : ", fo.mode)
#print("末尾是否强制加空格 : ", fo.softspace)
fo.write("www.runoob.com!\nVery good site!");
fo.seek(0, 0);
str = fo.read(10);
print("fileContent:" + str)
fo.close()```
**文件目录操作**
import os
重命名文件test1.txt到test2.txt。
os.rename( "test1.txt", "test2.txt" )
删除一个已经存在的文件test2.txt
os.remove("test2.txt")
创建目录test
os.mkdir("testdir")
将当前目录改为"/home/newdir"
os.chdir("/home/newdir")
给出当前的目录
print(os.getcwd())
删除”/tmp/test”目录
os.rmdir( "/tmp/test" )
打开文件,若文件不存在,则关闭文件 相当于try...finally...
with open('/path/to/file', 'r') as f:
print(f.read())
**面向对象**
类的声明和调用.一般类是写在单独的一个文件中
!/usr/local/bin/python3
coding=utf-8
class Employee:
'所有员工的基类'
empCount = 0
def init(self, name, salary):
self.name = name
self.salary = salary
Employee.empCount += 1
def displayCount(self):
print("Total Employee %d" % Employee.empCount)
def displayEmployee(self):
print("Name : ", self.name, ", Salary: ", self.salary)
def del(self):
print("析构函数执行")
"创建 Employee 类的第一个对象"
emp1 = Employee("Zara", 2000)
"创建 Employee 类的第二个对象"
emp2 = Employee("Manni", 5000)
emp1.displayEmployee()
emp2.displayEmployee()
print("Total Employee %d" % Employee.empCount)
**继承**
python支持多重继承
class A: # 定义类 A
.....
class B: # 定义类 B
.....
class C(A, B): # 继承类 A 和 B
.....
你可以使用issubclass()或者isinstance()方法来检测。
- issubclass() - 布尔函数判断一个类是另一个类的子类或者子孙类,语法:issubclass(sub,sup)
- isinstance(obj, Class) 布尔函数如果obj是Class类的实例对象或者是一个Class子类的实例对象则返回true。
**分文件组织源码**
firstClass.py
!/usr/local/bin/python3
coding=utf-8
class firstClass(object):
"""docstring for firstClass"""
def init(self, arg):
super(firstClass, self).init()
self.arg = arg
def printMe(self):
print(__name__)
secondClass.py
!/usr/local/bin/python3
coding=utf-8
class secondClass(object):
"""docstring for secondClass"""
def init(self, arg):
super(secondClass, self).init()
self.arg = arg
def printMe(self):
print(__name__)
hello.py
!/usr/local/bin/python3
coding=utf-8
import firstClass
import secondClass
class1 = firstClass.firstClass('a')
class2 = secondClass.secondClass('a')
class1.printMe()
class2.printMe()