0.python的安装相关
1.安装python3:sudo apt-get install python3
2.卸载python3:sudo apt-get remove python3
3.升级pip3:pip3 install -U pip
或:pip3 install --upgrade pip
4重装pip3(python3自带pip3)--先卸载,再安装
sudo python3 -m pip uninstall pip && sudo apt install python3-pip --reinstall
5.升级pip3报错解决方法
注意:由于若/usr/bin/pip3是只读文件,不加sudo ,可能会提示权限不足,若在只读权限下强制保存会导致文件受损,建议修改配置文件时先查看是否具有权限
修改的内容如下:
原文:from pip import main
修改后:from pip._internal import main
1.python的书写规范:pep8
文档:http://legacy.python.org/dev/peps/pep-0008/
1.缩进用4个空格
2.类名用首字母大写的驼峰写法,函数名用全小写,下划线隔开单词
3.一行代码最多79个字符
2.深入理解__init__
定义类的时候,若是添加__init__方法,那么在创建类的实例的时候,实例会自动调用这个方法,一般用来对实例的属性进行初始化
def __init__(self, name, gender)#定义 __init__方法,这里有三个参数,这个self指的是等一会创建类的实例的时候这个被创建的实例本身(例中的testman),你也可以写成其他的东西,比如写成me也是可以的,这样的话下面的self.Name就要写成me.Name。
self.Name=name #等号左边的那个Name/Gender是实例的属性,后面那个是方法__init__的参数,两个是不同的,表示将传参的值赋值给实例属性
print('hello') #这个print('hello')是为了说明在创建类的实例的时候,__init__方法就立马被调用了。
testman = TestClass('neo,'male') #这里创建了类testClass的一个实例 testman, 类中有__init__这个方法,在创建类的实例的时候,就必须要有和方法__init__匹配的参数了,由于self指的就是创建的实例本身,self是不用传入的,所以这里传入两个参数。这条语句一出来,实例testman的两个属性Name,Gender就被赋值初使化了,其中Name是 neo,Gender 是male。
In [22]: class TestClass (object):
...: def __init__(self, name, gender):
...: self.Name = name
...: self.Gender = gender
...: print ('hello')
...:
In [23]: testman=TestClass(name='neo',gender='male')#实例化对象时__init__已经被调用
hello
In [25]: print(testman.Name)
neo
In [26]: print(testman.Gender)
male
3.深入理解self
Python编写类的时候,每个函数参数第一个参数都是self,而且必须要写上。首先明确的是self只有在类的方法中才会有,独立的函数或方法是不必带有self的。self在定义类的方法时是必须有的,虽然在调用时不必传入相应的参数。
self名称不是必须的,在python中self不是关键词,你可以定义成a或b或其它名字都可以,但是约定成俗(为了和其他编程语言统一,减少理解难度),不要搞另类,大家会不明白的。
self代表的是实例本身,而不是类,因为类是是模板,模板抽象的,没有具体的属性/方法,实例化之后的实例才有
In [27]: class Test:
...: def ppr(self):
...: print(self)
...: print(self.__class__)
...:
...: t = Test()
...: t.ppr()
...:
...:
<__main__.Test object at 0x7fbcd44182b0>
<class '__main__.Test'>#这里的class指的是类实例
什么情况下可以不加self:
1.独立的函数,即不在类下的函数(一般类下的函数称为方法,即类方法,而独立类之外的函数称为函数)
2.当定义和调用类方法均不用传入实例时,可以不加self(即不能传参)
3.类下定义的方法定义时必须加入self(即有参数需要传入的都需要加self,所以一般都得加)
如下:
调用ppr1时传入了Test1类的实例t,所以会报错,这就是实例方法
调用ppr2时未将Test2类实例化,所以能够执行,这就是类方法
In [28]: class Test1:
...: def ppr1():
...: print('a')
...: print('b')
...:
...: t = Test()
...: t.ppr()
...:
...:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-28-fa683a9cb9b3> in <module>()
5
6 t = Test()
----> 7 t.ppr1()
TypeError: ppr() takes 0 positional arguments but 1 was given
In [31]: class Test2:
...: def ppr2():
...: print('a')
...:
...: Test2.ppr2()
a
4.深入理解闭包
闭包是由函数及其相关的引用环境组合而成的实体
(即:闭包=函数+引用环境,外层函数传入一个参数a, 内层函数传入一个参数b, 内层函数使用a和b, 最后返回内层函数)
5.静态方法、类方法和属性方法
静态方法:通过类直接调用,不需要创建对象,不会隐式传递self,指类本身,而不是类实例
类方法:可以通过类方法修改类属性,不能通过类方法访问实例属性
属性方法:把一个方法变成一个静态属性
python没有动态方法
In [9]: class A():
...: def a(obja):
...: print(obja)
...: @staticmethod
...: def b(objb): #静态方法
...: print(objb)
...: def c():
...: print('hello')
...: def d(self)
In [79]: class people:
...: country='china'
...: @classmethod
...: def getcountry(cls): #类方法
...: return cls.country
...: @classmethod
...: def setcountry(cls,country): 可以通过类方法修改类属性
...: cls.country=country
# 创建属性方法: @property
# 修改属性方法: @eat.setter
# 删除属性方法: @eat.deleter
class Dog(object):
def __init__(self,name):
self.name = name
self.__food = None
@property #把一个方便变为静态属性
def eat(self):
print("%s is eating %s" %(self.name,self.__food))
@eat.setter #属性方法修改,添加元素
def eat(self,food): #创建相同名称函数的方法名
print("set to food:",food)
self.__food = food
@eat.deleter #属性方法删除
def eat(self):
del self.__food
print("删完了")
d = Dog("ChenRonghua") #实例化
d.eat #不添加元素,输出
d.eat = "baozi" #赋值元素,需要两个同名函数
d.eat #赋值后输出
#输出结果
#ChenRonghua is eating None
#set to food: baozi
#ChenRonghua is eating baozi
#删完了
6.匿名函数
函数定义过程中,没有给定函数名,python中用lambda来创建匿名函数,lambda只是一个表达式,函数体比def简单,主体是表达式,不是代码块,仅能在lambda中封装有限的逻辑进去,lambda有自己的命名空间,不能访问自己参数列表之外的或者是全局命名空间的参数
#基础用法,创建函数表达式--不推荐使用
In [2]: ad=lambda x,y:x+y
In [3]: ad(1,2)
Out[3]: 3
#字典排序
In [4]: stu=[{"name":"c","age":1},{"name":"b","age":4},{"name":"e","age":3}]
In [6]: stu.sort(key=lambda x:x['name']) #sort是要改变源数据的
In [7]: print(stu)
[{'name': 'b', 'age': 4}, {'name': 'c', 'age': 1}, {'name': 'e', 'age': 3}]
In [10]: sorted(stu,key=lambda x:x['age']) #sorted生成新对象,不改变源数据
Out[10]: [{'name': 'c', 'age': 1}, {'name': 'e', 'age': 3}, {'name': 'b', 'age': 4}]
In [11]: stu
Out[11]: [{'name': 'b', 'age': 4}, {'name': 'c', 'age': 1}, {'name': 'e', 'age': 3}]
#作为函数变量
In [20]: def lamb(x,y,opt):
...: re=opt(x,y)
...: return re
In [21]: lamb(1,2,lambda x,y:x+y)
Out[21]: 3
7.递归函数
在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。
In [41]: def fact(n):
...: if n==1:
...: return 1
...: else:
...: return n*fact(n-1)
...:
In [42]: fact(5)
Out[42]: 120
"""
根据函数定义看到计算过程如下:
===> fact(5)
===> 5 * fact(4)
===> 5 * (4 * fact(3))
===> 5 * (4 * (3 * fact(2)))
===> 5 * (4 * (3 * (2 * fact(1))))
===> 5 * (4 * (3 * (2 * 1)))
===> 5 * (4 * (3 * 2))
===> 5 * (4 * 6)
===> 5 * 24
===> 120
"""
In [39]: def dream(n):
...: print('进入了第%d层梦境'%(n))
...: if n==3:
...: print('进入列潜意识')
...: else:
...: dream(n+1) #if..else调用自己,会循环完才会往下执行
...:
...: print('从第%d层梦境中醒来'%(n)) #else循环完后才会执行此句
In [40]: dream(1)
进入了第1层梦境
进入了第2层梦境
进入了第3层梦境
进入列潜意识
从第3层梦境中醒来
从第2层梦境中醒来
从第1层梦境中醒来
8.面向对象
对象
类
方法
封装
多态:在不同类下定义相同名称不同功能的函数,从而使函数拥有多种功能
class animal:
def jiao(self):
print('ao~~~')
class dog(animal):
def jiao(self):
print('wang!!!')
class cat(animal):
def jiao(self):
print('miao')
def test(obj):
obj.jiao()
a=animal()
a.jiao()
d=dog()
c=cat()
test(d)
test(c)
继承:即新定义的类继承原有类的属性和方法
class dog:
def __init__(self,name,color='black'): #单继承,一个类派生另外一个子类,子类继承父类的属性和方法
self.name=name
self.color=color
def run(self):
print('狗富贵,互相汪!!')
class taidi(dog):
def set_name(self,name):
self.name=name
def eat(self):
print('im eating!!')
gou=taidi('泰迪')
print('名字为%s'%gou.name)
print('颜色是%s'%gou.color)
gou.eat()
gou.set_name('erha')
print('旺财的新名字',gou.name)
gou.run()
#多继承,子类继承多个父类的属性和方法
class a:
def printa(self):
print('------------a------------')
class b:
def printb(self):
print('-----------b------------')
class c(a,b)
def printc(self):
print('-----------c------------')
c1=c()
c1.printa()
c1.printb()
c1.printc()
#父类重写,当子类中的方法和父类中方法名字一致时候,子类会重写父类
class dog:
def sayhi(self):
print('wang!!!!')
class fadou(dog):
def sayhi(self):
print('么么da~~~~')
dog1=fadou()
dog1.sayhi()
抽象
组合
9.类属性的访问特性
实例属性:无法通过类本身来访问实例属性,需要实例化后才可访问
类属性:我们可以通过类名及实例对象去访问
私有属性:私有属性无法通过类本身或类实例访问,只能通过内部方法访问,可以理解为局部变量
注意:python中没有c++,java等private、public这种关键字区分共有属性和私有属性,它是以__开头,否则为共有属性
In [71]: class func(object):
...: a=100 #类属性
...: def __init__(self,b,c):
...: self.b=b #实例属性
...: self.__c=c #实例属性,私有属性
...: def pri(self): #类方法
...: print(self.__c)
In [77]: func.a #类本身可以访问类属性
Out[77]: 100
In [78]: func.b #类本身无法访问实例属性
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-78-7036297ee1d3> in <module>()
----> 1 func.b
AttributeError: type object 'func' has no attribute 'b'
In [72]: f=func(200,300) #实例化
In [73]: f.a #类属性可以通过类本身/类实例访问
Out[73]: 100
In [74]: f.b #实例属性需要实例化后访问
Out[74]: 200
In [75]: f.pri() #私有属性只能通过类方法访问
300
In [76]: f.__c #私有属性无法通过类本身/类实例访问
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-76-e8a29e45f923> in <module>()
----> 1 f.__c
AttributeError: 'func' object has no attribute '__c'
10.装饰器
不用修改函数源代码的情况下给函数赋予新的功能
简单原理既是使用了嵌套函数,在嵌套函数中调用原函数,再返回嵌套的函数,从而使原函数使用装饰器可以达到不修改代码,而实现被赋予新功能
#计算一个函数的运行时间
import time
def jisuan(func):
def zsq():
startime=time.time()
func()
endtime=time.time()
sec=endtime-startime
print('消耗时间为%d'%sec)
return zsq
@jisuan
def func():
print('hello')
time.sleep(1)
print('world')
f=func
f()
#带有参数的装饰器
import time
def dec(func):
def jisuan(a,b):
starttime=time.time()
func(a,b)
endtime=time.time()
sec=endtime-starttime
print('time is %d'%sec)
return jisuan
@dec
def func(a,b):
print('a+b=?')
time.sleep(1)
print('its',a+b)
f=func
f(4,5)
11.深入理解深复制、浅复制
浅复制:在新内存地址上存拷贝数据,修改新数据,不改变源数据。
深复制:复制源数据的的内存地址,修改新数据,不改变源数据
12.异常
a.异常
程序执行过程中发生影响程序正在执行的事件,当python无法正常处理时候就会产生异常。
异常是python中的一个对象,表示一个错误
捕获异常:为了防止python程序中止,当脚本发生异常时候需要捕获
b.常见异常
1.NameError
没有定义变量就直接使用
p
2.SyntaxError
语法错误
if a
3.IO Error
FileNotFoundError
文件操作不存在等
p=open('/home/heygor/test123','r')
4.ZeroDvisionEoor
被除数为0
10/0
5.valueError
int('d')
c.异常处理的方式
1.try ...except
有可能发生错误的代码放在try和except中间
try:
j
except NameError as e:
print('catch error!!!')
2.try...except...else
语法:
try:
代码
except:
代码
else:
代码
#如果没有报错可以执行其他操作
3.try-finally
语法:
try:
代码
finally:
代码
#如果没有捕获到异常代码执行
#如果捕获到异常,先执行这段代码,然后处理异常 #无论如何都会执行
try:
f=open('test','r')
print(f.read())
finally:
print('im living!!!')
4.try...except..finally
语法:
try:
代码
except:
代码
finally:
代码
#如果try没有捕获到异常,执行finally语句
#图过捕获到了异常,显出离异常,在执行finally
try:
f
except NameError as e:
print('catch error !!!')
finally:
print('找不到吧?')
5.try..except...else...finally
合体
13.终端字体颜色
终端的字符颜色是用转义序列控制的,是文本模式下的系统显示功能,和具体的语言无关。
转义序列是以ESC开头,即用\033来完成(ESC的ASCII码用十进制表示是27,用八进制表示就是033)。
书写格式:
开头部分:\033[显示方式;前景色;背景色m + 结尾部分:\033[0m
注意:开头部分的三个参数:显示方式,前景色,背景色是可选参数,可以只写其中的某一个;另外由于表示三个参数不同含义的数值都是唯一的没有重复的,所以三个参数的书写先后顺序没有固定要求,系统都能识别;但是,建议按照默认的格式规范书写。 对于结尾部分,其实也可以省略,但是为了书写规范,建议\033[***开头,\033[0m结尾。
数值表示的参数含义:
显示方式: 0(默认值)、1(高亮)、22(非粗体)、4(下划线)、24(非下划线)、 5(闪烁)、25(非闪烁)、7(反显)、27(非反显)
前景色: 30(黑色)、31(红色)、32(绿色)、 33(黄色)、34(蓝色)、35(洋 红)、36(青色)、37(白色)
背景色: 40(黑色)、41(红色)、42(绿色)、 43(黄色)、44(蓝色)、45(洋 红)、46(青色)、47(白色)
常见开头格式:
\033[0m 默认字体正常显示,不高亮
\033[32;0m 红色字体正常显示
\033[1;32;40m 显示方式: 高亮 字体前景色:绿色 背景色:黑色
\033[0;31;46m 显示方式: 正常 字体前景色:红色 背景色:青色
实例:
(1)print("\033[1;31;40m您输入的帐号或密码错误!\033[0m")
上方代码的输出格式为:字体高亮,红色前景,黄色背景 PS:前景色也就是字体的颜色
(2)print("\033[0;31m%s\033[0m" % "输出红色字符")
#上方代码的输出格式为:字体默认,红色前景