一、字符串
1. 字符串切片
切片:
name="abcdef” name[2:5]="cde”
跳取:
name="abcdef” name[2:-1:2]="ce”
逆序:
name="abcdef” name[-1::-1]="fedcba”
2.字符串的常见操作
find:检测 str 是否包含在 mystr中,如果是返回开始的索引值,否则返回-1。
mystr.find(str, start=0,end=len(mystr))
index:跟find()方法一样,只不过如果str不在 mystr中会报一个异常。
mystr.index(str, start=0,end=len(mystr))
count:返回 str在start和end之间 在mystr里面出现的次数。
mystr.count(str, start=0, end=len(mystr))
replace:把 mystr 中的 str1 替换成 str2,如果 count 指定,则替换不超过 count 次。
mystr.replace(str1, str2, mystr.count(str1))
split:以str 为分隔符切片mystr,如果 maxsplit有指定,则仅分隔 maxsplit 个子字符串。
mystr.split(str=" ", 2)
capitalize:把字符串的第一个字符大写。
mystr.capitalize()
title:把字符串的每个单词首字母大写。
mystr.title()
startswith:检查字符串是否是以obj开头, 是则返回 True,否则返回 False。
mystr.startswith(obj)
endswith:检查字符串是否以obj结束,如果是返回True,否则返回 False。
mystr.endswith(obj)
lower:转换 mystr 中所有大写字符为小写。
mystr.lower()
upper:转换 mystr 中的小写字母为大写。
mystr.upper()
ljust:返回一个原字符串左对齐,并使用空格填充至长度 width 的新字符串。
mystr.ljust(width)
rjust:返回一个原字符串右对齐,并使用空格填充至长度 width 的新字符串。
mystr.rjust(width)
center:返回一个原字符串居中,并使用空格填充至长度 width 的新字符串。
mystr.center(width)
lstrip:删除 mystr 左边的空白字符。
mystr.lstrip()
rstrip:删除 mystr 字符串末尾的空白字符。
mystr.rstrip()
strip:删除mystr字符串两端的空白字符。
mystr.strip()
rfind:类似于 find()函数,不过是从右边开始查找。
mystr.rfind(str, start=0,end=len(mystr))
rindex:类似于 index(),不过是从右边开始。
mystr.rindex( str, start=0,end=len(mystr))
partition:把mystr以str分割成三部分,str前,str和str后。
mystr.partition(str)
rpartition:类似于 partition()函数,不过是从右边开始。
mystr.rpartition(str)
splitlines:按照行分隔,返回一个包含各行作为元素的列表。
mystr.splitlines()
isalpha:如果 mystr 所有字符都是字母则返回 True,否则返回 False。
mystr.isalpha()
isdigit:如果 mystr 只包含数字则返回 True 否则返回 False。
mystr.isdigit()
isalnum:如果 mystr 所有字符都是字母或数字则返回 True,否则返回 False。
mystr.isalnum()
isspace:如果 mystr 中只包含空格,则返回 True,否则返回 False。
mystr.isspace()
join:mystr 中每个字符后面插入str,构造出一个新的字符串。
mystr.join(str)
3.字符串常见问题
①字符串是不可变类型,是不能直接就改的,那么就先要将其转化为列表,然后在循环中找到该元素,通过列表进行更改。
for i,string in enumerate(list):
if string == "love":
list[i]="automn"
二、列表
1.列表的相关操作
(1)添加元素("增"append, extend, insert)
list.append(obj): 通过append可以向列表添加元素。
list.extend(obj): 通过extend可以将另一个集合中的元素逐一添加到列表中。
list.insert(index,obj):在指定位置index前插入元素object。
(2)删除元素("删"del, pop, remove)
del:根据下标进行删除,del list[i]。
pop:删除最后一个元素,list.pop()。
remove:根据元素的值进行删除,list.remove("obj")。
(3)修改元素("改OBJ[i] = "X"")
修改元素的时候,要通过下标来确定要修改的是哪个元素,然后才能进行修改。
(4)查找元素("查"in, not in, index, count)
in(存在),如果存在那么结果为true,否则为false。
not in(不存在),如果不存在那么结果为true,否则false。
index和count与字符串中的用法相同。
(5)排序(list.sort(cmp = None,key = None,reverse = False))
sort方法是将list按特定顺序重新排列,默认为由小到大,参数reverse=True可改为倒序,由大到小,list.sort() | list.sort(reverse=True)。
reverse方法是将list逆置,list.reverse()。
reverse=True就是从大到小,key=len就是长度划分,reverse=True就是列表倒序。
2.列表与字符串对比及转化
(1)列表和字符串的相同点
索引,切片,合并
(2)列表和字符串的不同点
在字符串中,每个元素只能是字符,在列表中,元素可以任意类型
列表可以改变,字符串不能改变
(3)列表和字符串的转化
mystr.split(" "):可以使字符串以空格方式隔开并以列表存放
".".join(list):列表可以用"."来连接列表的元素
3.列表常见问题
漏删元素。
num = [11,22,33,44,55,66]
for i in num:
if i == 33 or i == 44:
num.remove(i)
解释:此时的结果是num = [11,22,44,55,66],即出现了漏删的情况,因为删完33时,44往前挪一位,即跳过了它。
解决:要想避免漏删就要在这个外面加上一个while True死循环,也可以把要删的全部组合成另一个列表b,然后一个for循环,for i in b: num.remove(b)。
三、字典
1.字典的相关操作
(1)添加元素(变量名['键'] = 数据)
这个键在字典中,不存在,那么就会新增这个元素。
(2)删除元素(del,clear())
del 变量名["键"]:删除指定元素
del 变量名:删除整个字典
变量名.clear():删除整个字典
(3)修改元素(字典的每个元素中的数据是可以修改的,只要通过key找到,即可修改)
变量名['键'] = 数据
2.字典的常见操作
len:测量字典中,键值对的个数。
len(dict)
keys:返回一个包含字典所有KEY的列表。
dict.keys()
values:返回一个包含字典所有value的列表。
dict.values()
items:返回一个包含所有 (键,值) 元组的列表。
dict.items()
has_key: 如果key在字典中,返回True,否则返回False。
dict.has_key(key)
get: 获得某个键的值。
dict.get(key)
dict["key"] # 也可获取值但如果键不存在,就会异常,而dict.get()只返回一个空
setdefault:如果有这个键就会返回它的值,没有的话就创建这个键值对。
dict.setdefault(key)
items/iteritems,key/iterkeys,values/itervalues
# 能够得到字典的列表,元素是键和值的元组
infor.items()
# 是一个"dictionary-itemiterator"类型,这种迭代器类型,必须用list转换一下,才能看到里面的真面目
infor.iteritems()
3.字典常见问题
①dict = {} ,并不是真正意义的清空,它只是指向了另一个对象。
②不能重复删除同一个键,即删除一个没有键会发生异常。
③可变类型在字典中不能当作键值 (原因是它可变,故地址不确定)。
四、元组和集合
1.列表和元组
基本没什么区别,都能存多个值,唯一的区别就是元组不让增删改(只读)。
2.元组的内置函数
①cmp(tuple1,tuple2):比较两个元组元素。
②len(tuple):计算元组元素个数。
③max(tuple):返回元组中元素最大值。
④min(tuple):返回元组中元素最小值。
⑤tuple(seq):将列表转换为元组。
3.集合的去重
可以用set()来去重复,也可以set = {},但并不推荐,因为容易与字典相混淆。
4.集合常用操作
(1)增:set.add("jack") # 新添加元素
set.update("huang") #从另一个集合合并到一起。
(2)删:pop,remove,discard,clear
set.pop()不能有参数,且是随机删除,当删除到集合为空如果还继续删除则发生异常。
set.remove("obj") 删除指定的元素,没有则发生异常。
set.discard("obj") obj是set里的元素就删除,不是就不做,不发生异常。
set.clear()清空整个集合。
5.元素和集合的关系
"obj" in set ,元素在集合内就返回True,没有就返回False。
6. 集合与集合关系
①相等与不等:a==b,a!=b ,正确就返回True,错误就返回False。
②子集:c
③并集:a.union(b) ,把a集合和b集合并起来。
④交集:a.intersection(b) ,把a集合和b集合交起来。
五、函数
1.函数的定义
把具有一个独立功能的代码块当作一个整体,这个整体就是函数。
2.函数的目的
使程序变的更加模块化。
3.实参
当调用一个函数的时候,传递的值叫实参(实实在在传递的)。
4.形参
用来接收的叫形参,过程希望调用时,传递该值。
5.局部变量
在一个函数里能用,出了这个函数哪都用不了,这样的变量称为局部变量。
6.全局变量
定义在函数外面的变量,在整个代码中都可使用。
7.修改全局变量的值
在修改语句前加上global变量名,这是对一个全局变量的声明,但是列表和字典可加可不加。
8.规避命名相同
全局变量和局部变量名字相同,在函数里会使用局部变量,默认是定义,为了规避全局变量和局部变量名字相同,定义全局变量的时候g_a=100。
9. 函数的缺省参数
调用函数时,缺省参数的值如果没有传入,则被认为是默认值,带有默认值的参数一定要位于参数列表的最后面,如print默认是换行,有了end就是就不换行。
10.函数返回多值
如果需要用一个函数返回多个值,但是在函数中只要执行到一个return,就返回结束,所以可以通过列表或元组来封装变量的值。
11.不定长参数
如test(a,b,c=33, *args, **kwargs)形参,如果实参在传递的时候有变量名的赋值就是字典的形式存储在kwargs中,没有变量名的就是args里。
12.命名空间
表示标识符的可见范围,它是对作用域的特殊抽象,它包含处于该作用域的标识符。
13.匿名函数的应用场合
①自己定义函数:函数作为参数传递,lambda x,y:x+y。
②作为内置函数的参数:lam = lambda x:x+3 ret = lam(3)。
③如果列表里是字典:infors.sort(key = lambdax:x[‘name’])(按name的首字母来排序)。
六、作用域
1.命名空间
变量命名的范围(变量起作用的范围)。
2.LEGB规则
Python 使用 LEGB 的顺序来查找一个符号对应的对象,即 locals -> enclosing function -> globals -> builtins 。
①locals,当前所在命名空间(如函数、模块),函数的参数也属于命名空间内的变量。
②enclosing,外部嵌套函数的命名空间(闭包中常见)。
③globals,全局变量,函数定义所在模块的命名空间。
④builtins,内建模块的命名空间。
在Python中,有一个内建模块,该模块中有一些常用函数,在Python启动后,且没有执行程序员所写的任何代码前,Python会首先加载该内建函数到内存。另外,该内建模块中的功能可以直接使用,不用在其前添加内建模块前缀,其原因是对函数、变量、类等标识符的查找是按LEGB法则,其中B即代表内建模块。
比如:内建模块中有一个abs()函数,其功能求绝对值,如abs(-20)将返回20。
七、面向对象
1.面向对象和面向过程的区别
①面向过程:根据业务逻辑从上到下写代码。
②面向对象:将数据与函数绑定到一起,进行封装,这样能够更快速的开发程序,减少了重复代码的重写过程(能让程序更加简单,更加紧凑面向对象和面向过程都是解决问题的一种思路而已)。
2.类和对象的关系
①对象是面向对象编程的核心,在使用对象的过程中,为了将具有共同特征和行为的一组对象抽象定义,提出了另外一个新的概念-类。
②类是抽象的,在使用的时候通常会找到这个类的一个具体的存在,使用这个具体的存在,一个类可以找到多个对象。某一个具体事物的存在,在现实世界中可以是看得见摸得着的,可以是直接使用的。
3.新式类和旧式类
①新式类:广度优先,从最接近的上一个类开始,依次往上寻找相应的继承属性。
②旧式类:深度优先,从最开始的类开始,依次往下寻找相应的继承属性。
4.类里面的方法和函数的区别
类里的方法和函数外观很相似,都采用def hanshu():,但是类的方法里必须要有一个形参,可以是self,可以是a,b,c,d等等,但是在调用的时候,实参里不能传递任何值。
5.类的内置方法
①__init__方法(给对象添加特定的属性)
②__str__方法(返回调用对象的信息)
③__del__方法(当删除一个对象时,Python解释器会默认调用这个方法,释放内存)
④__new__方法(__new__必须要有返回值,返回实例化出来的实例,至少要有一个参数cls)
6.测量对象的引用个数
导入sys模块,采用sys模块里的sys.getrefcount(对象),就会返回一个值,但是这个值比实际对象多1。
7.单例模式
确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,单例模式是一种对象创建模式,__instance = None,没有这个实例就创建。
8.内置命名空间,全局命名空间,本地命名空间
①内置命名空间:python运行起来,它们就存在了,内置函数的命名空间都属于内置命名空间。
②全局命名空间:每个模块创建它自己所拥有的全部命名空间,不同模块的全局命名空间彼此独立,不同模块中相同名称的命名空间,也会因为模块的不同步相互干扰。
③本地命名空间:模块中有函数或者类,每个函数或者类所定义的命名空间就是本地命名空间,如果函数返回了结果或者抛出异常,则本地命名空间也结束了。
9.公有属性和私有属性
①公有属性:可以被对象和方法直接访问。
②私有属性:不能通过对象直接访问,但能通过方法访问。
10. 类属性和实例属性
(1)类属性
类属性就是类对象所拥有的属性,它被所有类对象的实例对象所共有,只存在一个副本。
类属性,可以被所有类对象和实例对象访问,就好比是实例对象的共享属性称为类属性。
在给类添加属性的时候,该属性被放入类对象的__dict__魔法字典的键值对中。
(2)实例属性
不可变类型:实例属性不能左右类属性,但类属性能影响实例属性。
可变类型:实例属性和类属性之间可以互相改变。
在给实例添加属性的时候,该属性被放入实例对象的__dict__魔法字典的键值对中。
11. 类方法和静态方法
(1)类方法
是类对象所拥有的方法,需要用修饰器@classmethod来标识其为类方法。
第一个参数必须是类对象,一般以cls作为第一个参数。
可以对类属性进行修改,它不能访问实例属性。
可以被类对象和实例对象访问。
(2)静态方法
要通过修饰器@staticmethod来进行修饰,静态方法不需要多定义参数。
它无法访问实例变量,类,和实例属性。
可以被类对象和实例对象调用。
12.公有方法和私有方法
①公有方法:调用就可以执行,还可以调用私有方法。
②私有方法:一般表示是比较重要的方法,且一般需要获得一定条件才可调用,称为是私有方法。
13.继承与多继承
①被继承者称为父类 (基类),继承者称为子类 (派生类)。
②在继承的过程中,父类的私有属性,私有方法,也就是由双下划线__test():组成的不能继承。
③继承的意义与好处
可以实现代码复用,但也不是全部复用,可能不用。
实现属性和方法继承。
④只有父类的公有方法能访问父类的私有属性和私有方法,子类的公有方法没有访问权限。
14.重写与调用
①重写就是把方法与父类同样的定义一遍。
②如果发现在继承的时候,父类的方法的名字就是想要的名字,但不是想要的功能的时候,那么这个时候就可以去重写。
③调用被重写:类名.方法(self),super().方法()。
④每次在继承的时候,要把__init__()方法继承下来。
15.多态
是指面向对象程序执行时,相同的信息可能会送给多个不同的类别对象,系统可根据对象所属类别,引发对应类别方法而有不同的行为。
16.面向对象常见问题
(1)逻辑属性要用方法来赋值
在给对象设置属性的时候,直接赋予的话,可能某种情况下会发生不合逻辑的情况,如dog.age = -10,如果用方法来赋值,这样可以引入判断,如if new_age >0: self.age = new_age
(2)解耦合
如果类与类之间的耦合性过强,也就是一个类改变,另一个类也需要改变,此时可以定义一个函数,把其中一个类的方法形参传递到这个函数中,再在这个函数里返回到类中,这种思维叫做解耦。
(3)工厂方法模式
工厂方法模式让类的实例化推迟到子类,抽象的CarStore提供了一个创建对象的方法createCar,也叫作工厂方法。
八、异常
1.异常的介绍
解释器无法继续执行,出现了一些错误的提示,这就是所谓"异常">。
2.捕获异常
①把可能出现问题的代码,放在try中。
②把处理异常的代码,放在except中。
③当捕获多个异常时,可以把要捕获的异常的名字,放到except 后,并使用元组的方式进行存储。
3.异常的传递
如果一个异常是在一个函数中产生的,例如函数A---->函数B---->函数C,而异常是在函数C中产生的,那么如果函数C中没有对这个异常进行处理,就会传递到函数B中,以此类推。
4.自定义异常
用raise语句来引发一个异常。异常/错误对象必须有一个名字,且它们应是Error或Exception类的子类,抛出异常直接默认raise 。
5.assert断言语句
assret是语句等价于布尔真的判断,发生异常就意味着表达式为假,当条件不满需就会报错。
九、模块
1.模块的介绍
模块就好比是工具包,要想使用这个工具包中的工具(就好比函数),就需要导入这个模块。
2.制作模块
为了让我们自己写的模块被python解释器知道,需要用sys.path.append("路径"),但这种情况下,比如在交互模式下,如果关闭了,再开启,还要重新告知。
常用方法:设置PYTHONPATH环境变量。
vim /etc/profile
export PATH = /home/jack/python:$PAT
3.__all__控制模块的导入行为
from test import *时,为了防止把不需要的模块导入,在模块里边新建一个变量__all__,放上将来要使用的函数,类,全局变量的名字,如果不放,别人就无法使用__all__ =["Tset","test"]。
4. __init__.py控制包的导入行为
①包将有联系的模块组织在一起,即放到同一个文件夹下,并且在这个文件夹创建一个名字为__init__.py文件,那么这个文件夹就称之为包。
②这个__init__.py控制着包的导入行为,在这个文件中, 定义一个__all__变量,它控制着 from 包名 import *时导入的模块,如__all__ = ["sendmsg"]。
5.模块发布
①编辑setup.py
from distutils.core import setup
setup(name="dongGe", version="1.0", description="dongGe's module",author="dongGe",py_modules=['test.sendmsg', 'test.recvmsg'])
②构建模块
python/python3 setup.py build
③生成发布压缩包
python/python3 setup.py sdist
6.模块安装使用
①找到模块的压缩包。
②解圧。
③进入文件夹。
④执行命令python setup.py install。
⑤模块的引入。
from 模块名 import 模块名或者*
7.给程序传参数
import sys
name = sys.argv[1]
8.循环导入
①循环导入就是程序在导入某个模块的过程中,该模块里的函数又需要导入自身的这个模块,如此进入死循环。
②避免循环导入:所有在开发的过程中,开发者们写的模块不能相互调用,即应该相互隔开,然后由架构师来负责整体的模块调用使用,也就是上下设计分层,降低耦合。
9.重新导入模块
模块被导入后,如果某一方更新了这个模块,但是import module不能重新导入模块,重新导入需用from imp import *,然后再使用reload(test)即可重新导入。
十、Python基础补充
1.常用关键字
if/else/for/break/import/class/None/not/in/from/return/elif/and/or/True
False/try/except/global/lambda/pass/raise/del/def/continue/finally/as/while
2.静态语言
先确定功能,再执行。
3.动态语言
写完代码,运行的一霎那,功能才被确定。
4.输入强制转换为公式
如在转换输入类型的时候使用func_new = eval(func_new)就可转换成公式,即所有的输入都将转换为输入,与int是一个道理。
5.is和==的区别
①判断两者内容用==。
②判断两者是否指向同一个用is。
③如果是数字则在-5到+125,==和is都为True,过了这个范围两者就不指向一个对象了。