Python学习笔记:基础
本文根据廖雪峰的博客,学习整理笔记。主要内容有:基本数据类型,容器数据类型,变量及其作用域,判断及循环语法,函数式编程,面向对象,模块等概念。
数据类型
在python中,能够直接处理的数据类型有以下几种:
- 整数
- 浮点数
- 字符串
- 布尔值
- 空值
其他内置的数据类型:
- 列表 list 是一种有序的集合,例如 classmates = ['Michael', 'Bob', 'Tracy']
- len() 获取个数
- list[0] 取值
- apend('tom') 追加元素到末尾
- insert(1,'tom') 插入指定元素
- pop(1) 删除指定位置元素,不传参数删除末尾元素
- 元祖 tuple 和list类似,一旦初始化就不能修改,例如 classmates = ('Michael', 'Bob', 'Tracy')
- 只有一个元素的元祖可以表示为 t = (1,)
- 没有append(),insert()这样的方法
- 字典 dict 全称dictionary,类似java中map,使用键值对存储,例如 d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
- 取值 d['Michael']
- 判断key值是否存在,通过in判断,'Tom' in d, 或者get(),不存在返回None
- 删除一个key,用pop(key)方法,对应的value以会删除
- dict的key必须是不可变对象,在python中字符串、整数等都是不可以变的,可以作为key。而list不可变,不能作为key
- set 和list类似,但是没有重复的元素,set的原理和dict一样,set存放的是key,没有value。要创建一个set,需要提供一个list作为输入集合,例如 s = set([1, 2, 3]) ,打印出的结果是 {1,2,3}
- add(key) 添加元素
- remove(key) 删除元素
变量
这种变量本身类型不固定的语言称之为动态语言,与之对应的是静态语言。静态语言在定义变量时必须指定变量类型,如果赋值的时候类型不匹配,就会报错。
字符串和编码
现在计算机系统通用的字符编码工作方式:在计算机内存中,统一使用Unicode编码,当需要保存到硬盘或者需要传输的时候,就转换为UTF-8编码。
由于Python的字符串类型是str,在内存中以Unicode表示,一个字符对应若干个字节。如果要在网络上传输,或者保存到磁盘上,就需要把str变为以字节为单位的bytes。
Python对bytes类型的数据用带b前缀的单引号或双引号表示。
函数
判断:
if case1:
do1
elif case2:
do2
elif case3:
do3
else:
do4
循环:python中循环有两种,一种是for...in循环,依次把list或tuple中每个元素迭代出来;第二种是while循环
names = ['Michael', 'Bob', 'Tracy']
for name in names:
print(name)
python内置函数range(),可以生成一个整数序列,在通过list()函数可以转换为list。例如 list(range(5))
sum = 0
n = 99
while n > 0:
sum = sum + n
n = n - 2
print(sum)
在循环中,break语句可以提前退出循环,continue可以跳过当前这次循环。
计算机程序中,函数就是最基本的一种代码抽象的方式。
函数名其实就是指向一个函数对象的引用,完全可以把函数名赋给一个变量,相当于给这个函数起了一个“别名”,例如:
>>> a = abs # 变量a指向abs函数
>>> a(-1) # 所以也可以通过a调用abs函数
1
定义函数,使用def语句,依次写出 函数名 括号 括号中的参数 冒号,然后,在缩进快中编写函数体,函数的返回值用return语句返回。如果没有return语句,函数执行完毕后也会返回结果,只是结果为None。retrun None可以简写为return。
def my_abs(x):
if x >= 0:
return x
else:
return -x
空函数:如果想定义一个什么事也不做的空函数,可以用pass语句:
def nop():
pass
参数检查:调用函数时,如果参数个数不对,Python解释器会自动检查出来,并抛出TypeError。数据类型检查可以用内置函数isinstance()实现。
返回多个值:可以返回多个值,但这其实只是一种假象,返回值是一个tuple,返回一个tuple可以省略括号,而多个变量可以同时接收一个tuple,按位置赋给对应的值。例如:
import math def move(x, y, step, angle=0):
nx = x + step * math.cos(angle)
ny = y - step * math.sin(angle)
return nx, ny
函数的参数:
默认参数,默认参数必须指向不变对象
def power(x, n=2):
s = 1
while n > 0:
n = n - 1
s = s * x
return s
可变参数,在参数前面加了一个*号,参数numbers接收到的是一个tuple,调用该函数时,可以传入任意个参数
def calc(*numbers):
sum = 0
for n in numbers:
sum = sum + n * n
return sum
关键字参数,关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict
def person(name, age, **kw):
print('name:', name, 'age:', age, 'other:', kw) # 调用后
>>> person('Adam', 45, gender='M', job='Engineer')
name: Adam age: 45 other: {'gender': 'M', 'job': 'Engineer'}
# 复杂调用
>>> extra = {'city': 'Beijing', 'job': 'Engineer'}
>>> person('Jack', 24, city=extra['city'], job=extra['job'])
name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}
# 简化后,**extra表示把extra这个dict的所有key-value用关键字参数传入到函数的**kw参数,
# kw将获得一个dict,注意kw获得的dict是extra的一份拷贝,对kw的改动不会影响到函数外的extra
>>> extra = {'city': 'Beijing', 'job': 'Engineer'}
>>> person('Jack', 24, **extra)
name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}
命名关键字参数,如果要限制关键字参数的名字,就可以用命名关键字参数,例如,只接收city和job作为关键字参数。和关键字参数**kw不同,命名关键字参数需要一个特殊分隔符*,*后面的参数被视为命名关键字参数。
def person(name, age, *, city, job):
print(name, age, city, job) # 调用方式
>>> person('Jack', 24, city='Beijing', job='Engineer')
Jack 24 Beijing Engineer
参数组合,在Python中定义函数,可以用必选参数、默认参数、可变参数、关键字参数和命名关键字参数,这5种参数都可以组合使用。但是请注意,参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。
def f1(a, b, c=0, *args, **kw):
print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw) def f2(a, b, c=0, *, d, **kw):
print('a =', a, 'b =', b, 'c =', c, 'd =', d, 'kw =', kw)
错误
python中也是采用了 try...except...finally... 的错误处理机制。
调用栈:如果错误没有被捕获,它就会一直往上抛,最后被python解释器捕获,打印一个错误信息,然后程序退出。
记录错误:python内置的loggin模块可以非常容易记录错误信息。
import logging
logging.basicConfig(level=logging.INFO)
def foo(s):
return 10 / int(s)
def bar(s):
return foo(s) * 2
def main():
try:
bar('')
except Exception as e:
logging.exception(e)
main()
print('END')
抛出错误:因为错误是class,捕获一个错误就是捕获到该class的一个实例。因为,错误并不是凭空产生的,而是有意创建并抛出的。pyhton的内置函数会抛出很多类型的错误,我们自己编写的函数也可以抛出错误。python中用raise语句抛出一个错误的实例。raise语句如果不带参数,就会把当前错误原样抛出。
class FooError(ValueError):
pass
def foo(s):
n = int(s)
if n==0:
raise FooError('invalid value: %s' % s)
return 10 / n
foo('')
一个比较常见的错误处理方式:
def foo(s):
n = int(s)
if n==0:
raise ValueError('invalid value: %s' % s)
return 10 / n def bar():
try:
foo('')
except ValueError as e:
print('ValueError!')
raise bar()
捕获错误的目的只是记录一下,便于后续追踪,但是由于当前函数不知道应该怎么处理该错误,所以,最恰当的方式是继续往上抛,让顶层调用者去处理。
函数式编程
函数是Python内建支持的一种封装,我们通过把大段代码拆成函数,通过一层一层的函数调用,就可以把复杂任务分解成简单的任务,这种分解可以称之为面向过程的程序设计。函数就是面向过程的程序设计的基本单元。
函数式编程就是一种抽象程度很高的编程范式,纯粹的函数式编程语言编写的函数没有变量,因此,任意一个函数,只要输入是确定的,输出就是确定的,这种纯函数我们称之为没有副作用。而允许使用变量的程序设计语言,由于函数内部的变量状态不确定,同样的输入,可能得到不同的输出,因此,这种函数是有副作用的。
函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数!
Python对函数式编程提供部分支持。由于Python允许使用变量,因此,Python不是纯函数式编程语言。
函数名其实就是指向函数的变量,既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数(Higher-order function)。
def add(x, y, f):
return f(x) + f(y)
高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回。相关参数和变量都保存在返回的函数中,这种程序结构称为”闭包(Closure)”。
def lazy_sum(*args):
def sum():
ax = 0
for n in args:
ax = ax + n
return ax
return sum
匿名函数:关键字体lamba表示匿名函数。
装饰器:在函数调用前后对函数进行增强,但是又不希望修改原函数的定义,这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)。
import functools def log(text):
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
print('%s %s' % (text, func.__name__))
nest = func(*args, **kwargs)
print('end call')
return nest
return wrapper
return decorator @log('execute')
def now(who):
print(who + ' 2015-3-25') if __name__ == "__main__":
now('System say')
python的@语法,可以实现函数的增强功能。
生成器:可以参考这篇文章https://www.cnblogs.com/wongbingming/p/9060989.html
模块
为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少,很多编程语言都采用这种组织代码的方式。在Python中,一个.py文件就称之为一个模块(Module)。
为了避免模块名冲突,Python又引入了按目录来组织模块的方法,称为包(Package)。
请注意,每一个包目录下面都会有一个__init__.py的文件,这个文件是必须存在的,否则,Python就把这个目录当成普通目录,而不是一个包。__init__.py可以是空文件,也可以有Python代码,因为__init__.py本身就是一个模块,而它的模块名就是包名。
注意:如果 import package 即导入包名的话,只会导入 __init__.py 文件中的变量和函数。如果写做 from package import module 那么就是导入此包下的 module.py 中的变量和函数。
一个hello模块:
#!/usr/bin/env python3
# -*- coding: utf-8 -*- ' a test module ' __author__ = 'Michael Liao' import sys def test():
args = sys.argv
if len(args)==1:
print('Hello, world!')
elif len(args)==2:
print('Hello, %s!' % args[1])
else:
print('Too many arguments!') if __name__=='__main__':
test()
第1行和第2行是标准注释,第1行注释可以让这个hello.py文件直接在Unix/Linux/Mac上运行,第2行注释表示.py文件本身使用标准UTF-8编码;
第4行是一个字符串,表示模块的文档注释,任何模块代码的第一个字符串都被视为模块的文档注释;
第6行使用__author__变量把作者写进去,这样当你公开源代码后别人就可以瞻仰你的大名;
后面就开始是真正的代码部分。使用sys模块的第一步,就是导入该模块,第8行,但 import 指令,还会做一件重要的事情就是把 import 的那个 module 的代码执行一遍。
第19行和第20行的意思是,Python解释器把一个特殊变量__name__置为__main__,而如果在其他地方导入该hello模块时,if判断将失败,因此,这种if测试可以让一个模块通过命令行运行时执行一些额外的代码,最常见的就是运行测试。
变量和函数作用域:
- 私有的 private 通过下划线_前缀来实现
- 类似 __xxx__ 这样的变量是特殊变量,可以被直接引用,但是有特殊用途,一般我们自己的变量不要用这种变量名
- 公开的 pulic 正常的函数和变量名
安装第三方模块:一般来说,第三方库都会在Python官方的pypi.python.org网站注册,要安装一个第三方库,必须先知道该库的名称,可以在官网或者pypi上搜索。然后用包管理工具pip完成安装,例如 pip install package
面向对象
在Python中,所有数据类型都可以视为对象,当然也可以自定义对象。自定义的对象数据类型就是面向对象中的类(Class)的概念。
面向对象的设计思想是从自然界中来的,因为在自然界中,类(Class)和实例(Instance)的概念是很自然的。Class是一种抽象概念,比如我们定义的Class——Student,是指学生这个概念,而实例(Instance)则是一个个具体的Student,比如,Bart Simpson和Lisa Simpson是两个具体的Student。
在Python中,定义类是通过class关键字:
class Student(object):
def __init__(self, name, score):
self.__name = name
self.__score = score
def print_score(self):
print('%s: %s' % (self.name, self.score))
由于类可以起到模板的作用,因此,可以在创建实例的时候,把一些我们认为必须绑定的属性强制填写进去。通过定义一个特殊的__init__方法,在创建实例的时候,就把name,score等属性绑上去。
注意到__init__方法的第一个参数永远是self,表示创建的实例本身,因此,在__init__方法内部,就可以把各种属性绑定到self,因为self就指向创建的实例本身。
有了__init__方法,在创建实例的时候,就不能传入空的参数了,必须传入与__init__方法匹配的参数,但self不需要传,Python解释器自己会把实例变量传进去。
和普通的函数相比,在类中定义的函数只有一点不同,就是第一个参数永远是实例变量self,并且,调用时,不用传递该参数。除此之外,类的方法和普通函数没有什么区别,所以,你仍然可以用默认参数、可变参数、关键字参数和命名关键字参数。
可以使用type()函数来判断对象类型。
对于class的继承关系来说,使用type()就很不方便。我们要判断class的类型,可以使用isinstance()函数。
如果要获得一个对象的所有属性和方法,可以使用dir()函数,它返回一个包含字符串的list。
如果想要限制实例属性,可以在定义class的时候,定义一个特殊的__slots__变量,来限制该class实例能添加的属性。
Python中可以通过@property和@param.setter这个两个装饰器将普通方法变成属性调用,用起来和get/set一样。
Python中可以有多重继承,这种设计通常称之为 MixIn 。Java中不支持多继承,但是可以实现接口。
Python的class中有许多有特殊用途的函数,可以帮助我们定制类。
- __str__
- __iter__
- __getitem__
- __getattr__
- __call__
枚举:可以从Enum派生出自定义类,例如
from enum import Enum, unique @unique
class Weekday(Enum):
Sun = 0 # Sun ? value ???? 0
Mon = 1
Tue = 2
Wed = 3
Thu = 4
Fri = 5
Sat = 6 if __name__ == '__main__':
print(Weekday.Wed.value)
@unique装饰器可以帮助我们检查保证没有重复值
异常和错误
错误处理机制
try:
print('try...')
r = 10 / 0
print('result:', r)
except ZeroDivisionError as e:
print('except:', e)
finally:
print('finally...')
print('END')
python代码规范 https://www.python.org/dev/peps/pep-0008/
官方文档 https://docs.python.org/3/
Python学习笔记:基础的更多相关文章
- Python学习笔记基础篇——总览
Python初识与简介[开篇] Python学习笔记——基础篇[第一周]——变量与赋值.用户交互.条件判断.循环控制.数据类型.文本操作 Python学习笔记——基础篇[第二周]——解释器.字符串.列 ...
- Python 学习笔记---基础篇
1. 简单测试局域网中的电脑是否连通.这些电脑的ip范围从192.168.0.101到192.168.0.200 import subprocess cmd="cmd.exe" b ...
- Python学习笔记——基础篇【第一周】——变量与赋值、用户交互、条件判断、循环控制、数据类型、文本操作
目录 Python第一周笔记 1.学习Python目的 2.Python简史介绍 3.Python3特性 4.Hello World程序 5.变量与赋值 6.用户交互 7.条件判断与缩进 8.循环控制 ...
- Python学习笔记——基础篇【第四周】——迭代器&生成器、装饰器、递归、算法、正则表达式
目录 1.迭代器&生成器 2.装饰器 a.基本装饰器 b.多参数装饰器 3.递归 4.算法基础:二分查找.二维数组转换 5.正则表达式 6.常用模块学习 #作业:计算器开发 a.实现加减成熟及 ...
- VS2013中Python学习笔记[基础入门]
前言 在上一节中简单的介绍了在VS2013中如何进行开发Hello World,在VS2013中进行搭建了环境http://www.cnblogs.com/aehyok/p/3986168.html. ...
- Python学习笔记基础篇-(1)Python周边
一.系统命令 1.Ctrl+D 退出Python IDLE input方法中输入EOF字符,键入Ctrl+D 2.命令行选项: -d 提供调试输出 -O 生成优化的字节码(.pyo文件) -S 不 ...
- Python学习笔记——基础篇2【第三周】——计数器、有序字典、元组、单(双)向队列、深浅拷贝、函数、装饰器
目录 1.Python计数器Counter 2.Python有序字典OrderredDict 3.Python默认字典default 4.python可命名元组namedtuple 5.Python双 ...
- Python学习笔记——基础篇【第五周】——正在表达式(re.match与re.search的区别)
目录 1.正在表达式 2.正则表达式常用5种操作 3.正则表达式实例 4.re.match与re.search的区别 5.json 和 pickle 1.正则表达式 语法: import re # ...
- Python学习笔记——基础篇【第六周】——面向对象
Python之路,Day6 - 面向对象学习 本节内容: 面向对象编程介绍 为什么要用面向对象进行开发? 面向对象的特性:封装.继承.多态 类.方法. 同时可参考链接: http:// ...
- Python学习笔记——基础篇【第七周】———进程、线程、协程篇(socket基础)
http://www.cnblogs.com/wupeiqi/articles/5040823.htmlhttp://i.cnblogs.com/EditPosts.aspx?postid=55437 ...
随机推荐
- apache_php_mysql
软件下载 目前,Apache和PHP均未出现官方的64位版本. Apache 64位: http://www.blackdot.be/?inc=apache/binaries 这个安装文件我已经上传到 ...
- 使用 nodeJs 开发微信公众号(上传图片)
在给用户发送消息中涉及到的素材(图片.视频.音频.文章等)需要事先传到微信服务器,然后获得媒体id(media_id),然后把 media_id 传递给用户 上传分上传临时素材(只保存三天)和上传永久 ...
- element-ui Form表单校验
使用element-ui自带的表单校验,注意几个点: 1.el-form通过rules属性,绑定校验规则 2.el-form-item的prop属性,设置为需要校验的字段名 3.提交后二次校验 sav ...
- Django05-模型系统model
Object Relational Mapping(ORM) 一.ORM介绍 1.ORM概念对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关 ...
- 用java输入分数,得出分数等级
import java.util.Scanner;public class F { public static void main(String[] args) { // TODO 自动生成的方法 ...
- Spring_Four -- 团队项目设计完善&编码测试
团队项目设计完善&编码测试 1.文档<软件设计方案说明书>github地址:https://github.com/gzyt/SRS 2.项目集成开发环境 数据库:Mysql 5.0 ...
- python day07笔记总结
2019.4.4 S21 day07笔记总结 一.深浅拷贝 1.copy.copy() 浅拷贝 deep.copy() 深拷贝 2.一般情况 1.str/int/bool 是不可变类型 ...
- Win10 for Docker 安装 K8S
win 10 docker安装K8S中遇见的一些问题,记录下来方便自己以后避免采坑. 安装步骤: 1.安装Docker for windows.在docker官方下载,然后傻瓜式安装. 安装成功以后再 ...
- Json压缩工具
一般的json文件拥有很多的空格和注释,虽然读起来比较方便,但是在运行的时候是要占一些内存的. 于是json压缩工具就应运而生了,这个工具是用java做的,原理是: 1:在Eclipse中导出一个可运 ...
- TCP协议和UDP协议基础介绍
TCP协议和UDP协议区别 标签(空格分隔): TCP,udp TCP的三次握手 TCP被称为可靠的数据传输协议,主要是通过许多机制来实现的其中最主要的就是三次握手的功能,当然,TCP传送数据的机制非 ...