参考廖雪峰大神的python3.0教程,适用于有一定基础的Java程序员,会对比着Java来学习python。代码在PyCharm中运行通过,地址为github。本篇主要介绍python的一些基础知识,包括安装运行(PyCharm设置)、基础语法、函数、高级特性、函数式编程、模块等。在下一篇会介绍python面向对象相关的知识。
python简介
Python的哲学就是简单优雅,尽量写容易看明白的代码,尽量写少的代码
应用场景
- 首选是网络应用,包括网站、后台服务等等;
- 其次是许多日常需要的小工具,包括系统管理员需要的脚本任务等等;
- 另外就是把其他语言开发的程序再包装起来,方便使用。
优点
- 简洁优雅。
- 非常完善的基础代码库,覆盖了网络、文件、GUI、数据库、文本等大量内容
- 大量的第三方库
缺点
- 运行速度慢:Python是解释型语言,代码在执行时会一行一行地翻译成机器码。但是大量的应用程序不需要这么快的运行速度,因为用户根本感觉不出来
- 代码不能加密:如果要发布你的Python程序,实际上就是发布源代码
安装Python
linux下安装
|
|
从安装日志中可以看到python3自带pip,easyinstall,setup-tools
环境变量
环境变量添加,将刚才configure设置的地址添加到环境变量中:
内容:
source之后测试是否安装成功:
windows下安装
python-3.5.2官方下载地址
安装过程中,务必勾上,就不用自己添加到环境变量了
- [x] Add Python 3.5 to PATH
安装完后测试是否成功
解释器
当我们编写Python代码时,我们得到的是一个包含Python代码的以.py为扩展名的文本文件。要运行代码,就需要Python解释器去执行.py文件。安装python之后自带了CPython,就用这个 就可以了。
编译器
Windows下安装PyCharm,官方下载地址为pycharm-professional-2016.2.3,第一次打开的时候,选择激活方式为code,填入激活码(激活码来自互联网,仅供学习交流之用)
pycharm配置
配置的文件在github项目中,直接导入也可以,下载地址。不怕麻烦可以按下面一步步设置:
界面窗口设置:
1Appearance&&Behavior -> Appearance -> show tool windows bars编辑器设置:file -> Setting ->Editor
12345678910#设置Python自动引入包general > autoimport -> python :show popup#“代码自动完成”时间延时设置Code Completion -> Auto code completion in (ms):0 -> Autopopup in (ms):500#显示“行号”与“空白字符”Appearance -> 勾选“Show line numbers”、“Show whitespaces”、“Show method separators”设置编辑器“颜色与字体”主题Colors & Fonts -> Scheme name -> 选择黑色背景的主题“Darcula”->Sava as先保存一份->Size -> 设置为“14”#python文件默认编码File Encodings> IDE Encoding: UTF-8;Project Encoding: UTF-8;python文件模板设置:file and code template>python scripts
123456789101112131415161718192021#!/usr/bin/env python# -*- coding: utf-8 -*-"""__title__ = '$Package_name'__author__ = '$USER'__time__ = '$DATE'# code is far away from bugs with the god animal protectingI love animals. They taste delicious.┏┓ ┏┓┏┛┻━━━┛┻┓┃ ☃ ┃┃ ┳┛ ┗┳ ┃┃ ┻ ┃┗━┓ ┏━┛┃ ┗━━━┓┃ 神兽保佑 ┣┓┃ 永无BUG! ┏┛┗┓┓┏━┳┓┏┛┃┫┫ ┃┫┫┗┻┛ ┗┻┛"""
hello world
PyCharm
如果前面已经安装好PyCharm,就跟IntelliJ Idea一样,新建项目,新建py文件,直接运行就可以了。
后面的示例程序都是在PyCharm中直接运行即可。
当然也可以通过交互式命令行、文本形式、py脚本形式(linux)运行。
交互式命令行
|
|
文本形式
编辑文本hello-world.py,内容为:
执行
脚本形式
linux下如果想直接运行py脚本,在开头加上:
执行
Python基础
- #开头的语句是注释
- 语句以冒号:结尾时,缩进的语句视为代码块
- 4个空格的缩进
- 大小写敏感123456# print absolute value of an integer:a = 100if a >= 0:print(a)else:print(-a)
数据类型和变量
数据类型
数据类型跟Java类似,基本类型主要有以下几种:
- 整数
- 浮点数
- 字符串:单引号或者双引号,转义字符“\”
- 布尔值:True、False
- 空值:None1234567891011121314# 整数print(1)print(-8080)print(0xff00)# 浮点数print(1.23)print(12.3e8)# 字符串print('I\'m \"OK\"!')# 布尔值print(True)print(2 > 3)# 空值print(None)
变量
动态类型,“=”赋值任意类型
- 执行a = ‘ABC’,解释器创建了字符串’ABC’和变量a,并把a指向’ABC’:
- 执行b = a,解释器创建了变量b,并把b指向a指向的字符串’ABC’:
- 执行a = ‘XYZ’,解释器创建了字符串’XYZ’,并把a的指向改为’XYZ’,但b并没有更改:
- 所以,最后打印变量b的结果自然是’ABC’了。
常量
用全部大写的变量名表示常量。
字符串和编码
计算机编码类型
- ASCII编码:1 byte,只支持英文
- Unicode编码:2 byte,支持中文、英文
- UTF-8编码:可变长度1-6byte,英文字母1个字节,汉字通常3个字节,很生僻的字符被编码成4-6个字节。
| 字符 | ASCII | Unicode | UTF-8 | |||
|---|---|---|---|---|---|---|
| A | 01000001 | 00000000 | 01000001 | 01000001 | ||
| 中 | x | 01001110 | 00101101 | 11100100 | 10111000 | 10101101 |
- 在计算机内存中,统一使用2个字节的Unicode编码,当需要保存到硬盘或者需要传输的时候,就转换为可变长度的UTF-8编码。
- 用记事本编辑的时候,从文件读取的UTF-8字符被转换为Unicode字符到内存里,编辑完成后,保存的时候再把Unicode转换为UTF-8保存到文件。
- 浏览网页的时候,服务器会把动态生成的Unicode内容转换为UTF-8再传输到浏览器.很多网页的源码上会有类似的信息,表示该网页正是用的UTF-8编码
python编解码
bytes类型
bytes类型的数据用带b前缀的单引号或双引号表示。
纯英文可以用ascii编码成bytes,中文只能用UTF-8编码成bytes,所以最好统一用UTF-8
源码的中文处理
当你的源代码中包含中文的时候,就需要务必指定保存为UTF-8编码
格式化输出
与C语言类似,用占位符表示:%d、%f、%s、%x。其中,%%来转义表示一个%。
例如:小明的成绩从去年的72分提升到了今年的85分,请计算小明成绩提升的百分点,并用字符串格式化显示出’xx.x%’,只保留小数点后1位
python集合类型
| python集合类型 | 创建方式 | 对应Java类型 |
|---|---|---|
| list | [] | List |
| tuple | () | List |
| map | {} | Map |
| set | set() | set |
list:[]
list是一种有序的集合,可以随时添加和删除其中的元素。
list里面的元素的数据类型也可以不同,比如:
list元素也可以是另一个list,比如:
如果一个list中一个元素也没有,就是一个空的list,它的长度为0:
tuple:()
相当于不可变的list,没有append、insert方法,小括号表示。只有1个元素的tuple时,也会加一个逗号,以免你误解成数学计算意义上的括号
与java的final类似,虽然是不可变的,但是tuple中的list是可变的
dict:{}
类似于java的map,dict的key必须是不可变对象
注意:dict迭代时。
- Python 3.x 里面,利用 items()来迭代
- Python 2.x 里面,iteritems() 和 viewitems()方法已经废除
set
set和dict的唯一区别仅在于没有存储对应的value。创建set必须以list作为输入集合:
set可以看成数学意义上的无序和无重复元素的集合,因此,两个set可以做数学意义上的交集、并集等操作:
不变与可变
list是可变对象
str是不变对象
对于不变对象来说,调用对象自身的任意方法,也不会改变该对象自身的内容。相反,这些方法会创建新的对象并返回,这样,就保证了不可变对象本身永远是不可变的。
其实说这么多,就是类似于java中的final类型,不能改变对象的地址,但是可以改变内容。
条件判断
注意冒号和缩进,else if必须写成elif
循环
for
跟java类似
range(i1,i2,n)表示从i1到i2的数组,步进为n,range(i)表示range(0,i),n省略为1,list(range())表示转化成list
while循环
跟java类似
break和continue
跟java一样,break语句可以在循环过程中直接退出循环,而continue语句可以提前结束本轮循环
函数
内置函数
绝对值、求最大值
数据类型转换函数:
int、float、str、bool
定义函数
定义函数,以def开头。没有return语句,返回结果为None
在其他py文件中调用,则需要引入from _2_def.py import my_abs。当然,在PyCharm中只需要Alt+Enter引入。
空函数
空函数:
pass还可以用在其他语句里
返回多个值
游戏中经常需要从一个点移动到另一个点,给出坐标、位移和角度,就可以计算出新的新的坐标。Python函数返回的仍然是单一值,以tuple形式而已。
练习
请定义一个函数quadratic(a, b, c),接收3个参数,返回一元二次方程:ax2 + bx + c = 0的两个解。详解见:_3_function/quadratic.py
递归函数
跟java类似,也要小心栈溢出的问题
函数参数
必选参数
必须传入的参数
默认参数
- 必选参数在前,默认参数在后
- 当函数有多个参数时,把变化大的参数放前面,变化小的参数放后面。变化小的参数就可以作为默认参数
- 默认参数必须指向不变对象12345678def power(x, n=2):s = 1while n > 0:n -= 1s = s * xreturn sprint(power(5))print(power(5, 3))
可变参数
在入参数前面加了一个*号,表示可变参数在函数调用时自动组装为一个tuple
关键字参数
在入参数前面加了一个**号,在函数内部自动组装为一个dict
命名关键字
如果要限制关键字参数的名字,就可以用命名关键字参数。
已经有了一个可变参数,命名关键字参数就不再需要一个特殊分隔符*了:
参数组合
参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。
对于任意函数,都可以通过类似func(args, *kw)的形式调用它
小结
- 默认参数一定要用不可变对象,如果是可变对象,程序运行时会有逻辑错误!
- 要注意定义可变参数和关键字参数的语法:
- *args是可变参数,args接收的是一个tuple;
- **kw是关键字参数,kw接收的是一个dict。
- 调用函数时如何传入可变参数和关键字参数的语法:
- 可变参数既可以直接传入:func(1, 2, 3),又可以先组装list或tuple,再通过args传入:func((1, 2, 3));
- 关键字参数既可以直接传入:func(a=1, b=2),又可以先组装dict,再通过kw传入:func({‘a’: 1, ‘b’: 2})。
- 使用args和*kw是Python的习惯写法,当然也可以用其他参数名,但最好使用习惯用法。
- 命名的关键字参数是为了限制调用者可以传入的参数名,同时可以提供默认值。
高级特性
切片
- L[i1:i2]表示从第i个到第i-2个,间隔为1。i1为负数时,表示从倒数第-i1个开始。
- L[i1:]表示到最后一个
- L[:i2]表示前i2个
- L[i1:i2:n]表示从第i个到第i-2个,间隔为n。
- L[:]表示复制L12345678910111213141516171819202122232425262728L = ['Michael', 'Sarah', 'Tracy', 'Bob', 'Jack']# 切片print(L[0:3])print(L[1:3])print(L[-1])print(L[-3:-1])L1 = list(range(100))print(L1[1:20])# 前十个数print(L1[:10])# 后十个数print(L1[-10:])# 前十个数,没两个取一个print(L1[:10:2])# 所有数,每5个取一个print(L1[::5])# 复制一个listprint(L1[:])# tuple切片仍是tupleprint((0, 1, 2, 3, 4, 5)[:3])# 切片用于字符串切割s = 'ABCDEFG's1 = s[:3]s2 = s[-4:]print(s1, s2,)
迭代
任何可迭代对象都可以作用于for循环,包括我们自定义的数据类型,只要符合迭代条件,就可以使用for循环
列表生成式
运用列表生成式,可以快速生成list,可以通过一个list推导出另一个list,而代码却十分简洁
生成器
通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。在循环的过程中不断推算出后续的元素,这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。
- 把一个列表生成式的[]改成(),就创建了一个generator
- 一个函数定义中包含yield关键字,是一个generator函数,generator函数的“调用”实际返回一个generator对象
- generator函数在每次next(g)或者for循环调用的时候执行,yield返回结果,再次执行时从上次yield语句处继续执行1234567891011121314151617181920212223242526272829303132g = (x * x for x in range(10))print(next(g))print(next(g))#斐波拉契数列(Fibonacci),除第一个和第二个数外,任意一个数都可由前两个数相加得到:# 1, 1, 2, 3, 5, 8, 13, 21, 34, ...def fib(max):n, a, b = 0, 0, 1while n < max:yield ba, b = b, a + bn = n + 1return 'done'f = fib(6)print(f)for n in fib(6):print(n)# 杨辉三角def triangles():L = [1]while True:yield LL.append(0)L = [L[i-1] + L[i] for i in range(len(L))]n=0for t in triangles():print(t)n += 1if n == 10:break
迭代器
| 对比 | Iterable(可迭代对象) | Iterator(迭代器) |
|---|---|---|
| 特点 | 可以直接作用于for循环 | 可作用于next()函数的对象 |
| 举例 | 集合类型、generator | generator、iter(集合类型) |
集合数据类型:如list、tuple、dict、set、str等。
generator:包括生成器和带yield的generator function。
函数式编程
高阶函数
把函数作为参数传入,这样的函数称为高阶函数,函数式编程就是指这种高度抽象的编程范式
map/reduce
- map(函数,Iterator):将传入的函数依次作用到序列的每个元素(并行计算),并把结果作为新的Iterator返回
- map(f, [x1, x2, x3, x4]) = [f(x1), f(x2), f(x3), f(x4)]
- reduce(函数,Iterator):reduce把结果继续和序列的下一个元素做累积计算(串行计算)
- reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)123456789# 实现int函数:map利用dict将集合str挨个转换为数字,reduce加权累加每位def str2int(s):def fn(x, y):return x * 10 + ydef char2num(s):L = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}return L[s]return reduce(fn, map(char2num, s))print(str2int('123'))
- reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
filter
filter()用于过滤序列。把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。返回的是一个Iterator
sorted
语法:sorted(L, key=函数, reverse=True/False)
- L:序列
- key:排序规则
- reverse:是否逆序123456789L = [36, 5, -12, 9, -21]print(sorted(L))# sorted:keyprint(sorted(L, key=abs))s = ['bob', 'about', 'Zoo', 'Credit']print(sorted(s))print(sorted(s, key=str.lower))# # sorted:reverse=True逆序print(sorted(s, key=str.lower, reverse=True))
返回函数
- 返回的函数并没有立刻执行,而是直到调用了f()才执行
- 相关参数和变量都保存在返回的函数中,这种称为“闭包(Closure)”
- 返回函数不要引用任何循环变量,或者后续会发生变化的变量12345678910def lazy_sum(*args):def sum():ax = 0for n in args:ax = ax + nreturn axreturn sumf = lazy_sum(1, 3, 5, 7, 9)print(f)print(f())
匿名函数
- Lambda 函数相当于没有显式声明的函数,定义即用。
- 只能有一个单独的表达式1lambda x, y: x * y
相当于:
装饰器
在代码运行期间动态增加功能的方式,称之为“装饰器”。类似于java的Annotation。下述代码
- now()相当于执行log(now)
- tomorrow()相当于执行log(‘exective’)(now)
- @functools.wraps(func)是为了不改变函数的
__name__属性1234567891011121314151617181920212223242526272829303132import functoolsdef log(args):if isinstance(args, str):def decorator(func):@functools.wraps(func)def wrapper(*args, **kw):print('begin %s %s():'%(args,func.__name__))func(*args, **kw)print('end %s %s():'%(args,func.__name__))return wrapperreturn decoratorelse:func = args@functools.wraps(func)def wrapper(*args, **kw):print('begin call %s():' % func.__name__)func(*args, **kw)print('end call %s():'%func.__name__)return wrapper@logdef now():print('2015-3-25')now()@log('exective')def tomorrow():print('2017/2/13')now()tomorrow()
偏函数
当函数的参数个数太多,需要简化时,使用functools.partial可以创建一个新的函数,这个新函数可以固定住原函数的部分参数
模块
- 在Python中,一个.py文件就称之为一个模块(Module)
- 按目录来组织模块的方法,称为包(Package)
使用模块
|
|
安装第三方模块
安装
- 第三方模块搜索:下载地址
- pip安装:比如要做图片处理Pillow,1pip install Pillow
图片压缩
模块搜索路径
Python解释器会搜索当前目录、所有已安装的内置模块和第三方模块。搜索路径存放在sys模块的path变量中,查看sys.path
如果我们要添加自己的搜索目录,有两种方法:
- 一是直接修改sys.path,添加要搜索的目录:12>>> import sys>>> sys.path.append('/Users/michael/my_py_scripts')
这种方法是在运行时修改,运行结束后失效。
- 第二种方法是设置环境变量PYTHONPATH,该环境变量的内容会被自动添加到模块搜索路径中。
参考
http://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000
http://blog.csdn.net/pipisorry/article/details/39909057