匿名函数的动态使用,更加能够体现Python是一种动态语言
思考问题:
a+=a 和 a=a+a区别?
读写文件:
一般经常使用的读文件的方法是read()和readline()
tell()用来获取指针当前位置,seek()方法可以调整指针当前位置
递归的思想
tcp和udp的区别:
1.基于连接和无连接
2.对系统资源的要求(tcp多、udp少)
3.UDP程序结构简单
4.流模式和数据报模式
5.TCP保证数据的正确性,UDP可能丢包,TCP保证数据顺序,UDP不保证
小写的socket是个模块,模块里有个类也叫socket
线程和进程:
一个进程可拥有多个并行的线程
一个进程中的线程共享相同的内存单元/内存地址空间→可以访问相同的变量和对象,而且他们从同一堆中分配对象→通信,数据
交换,同步操作
由于线程间的通信是在同一地址空间上进行的,所以不需要额外的通信机制,这就使得通信更简便,传递速度更快
线程的 join()方法:这个方法调用后的意思是,等当前线程执行完毕后,程序才可以继续往下执行,比如这一方法在100行调用,那么101行程序需要等待调用此方法的线程执行完毕后,才可以被调用
面向对象和面向过程:
面向过程是把关注点放在动作和行为上,而面向对象是把关注点放在事物上
__init__()方法用于初始化对象,而不是构建对象
面向对象思维:只关注对象本身的行为,不属于对象的行为,不要乱写
面向对象的三大特性:封装、继承、多态。三者呈递进关系:由于封装先把属性和方法封装到一个类里,因此继承才有意义,才可以继承父类的属性和方法,然后才会有多态,一个父类可以被多种状态的子类所表示
只要是以两个_ _ 开头的方法或者属性,都是私有的,只要不是以两个_ _ 开头的都是公有的
__del__()方法:当内存中销毁(释放)一个对象时回调__del__()方法
del 变量名:会删除变量的引用!!!
子类无法继承父类的私有属性和私有方法
类方法__mro__():显示多继承之间的优先级关系
Python中没有重载,只有重写,只要父类和子类中含有相同的方法名称,那就是重写。
若想在子类中重写父类方法后,依然可以在子类中调用父类的方法,那就使用super().方法名()主动调用父类的方法
类属性:所属于类,所有实例化这个类的都可以访问。相当于Java的静态属性
类属性的修改和删除只能通过类属性
对象属性本质上不能被继承,真正能被继承的是类属性
静态方法是类方法的一种,不过没有装饰器不同,没有默认传递的参数
__new__()方法是一个静态方法,用来构建当前对象,必须有返回值,如果没有则不会调用__init__()方法,对象也不会被创建出来。如果子类继承父类后重写__new__()方法,并且没有返回父类的__new__()方法,则无法构建出一个新的对象,因此如果要重写此方法,必须返回父类的方法,单例模式就是利用这一原理,定义一个参数,限制参数不为默认值时只让它返回一次父类的方法,因此只会构建一次对象,这种方法也是有弊端的,可以通过调用父类的__new__()方法来返回一个构建的对象来绕过这个限制
# 单例
class A(object):
# 设置一个默认属性
__instance = None
def __new__(cls):
# 只有当 __instance 属性为默认值时,才调用父类方法创建一个对象
if not cls.__instance:
cls.is_instance = super().__new__(cls)
return cls.__instance
# 绕过上述的单例限制,实例化此类的一个对象
# 这是由于类继承object,并通过object进行构造一个对象
# 但是通过这样的方法构造的对象,解释器并没有调用此类的__init__()方法
# 理论上,调用的应该是object类的__init__()方法
a = object.__new__(A)
id()方法可以返回内存地址
异常相关:
else 除了和 if 搭配外,和其他关键词搭配的时候,都是在成功的情况下才会执行,如:else 搭配 try 语句,还有和for循环的搭配,细节需要查一查
出现异常的语句会把异常抛出,如果没有捕获,最后会抛给Python进程,并且异常语句之后的代码将不会执行,如果有 finally ,直接执行 finally 里的代码,finally 以外的都不会执行;如果进行了捕获,则抛出异常,try代码块里从异常语句开始后的代码将不会执行,异常抛给 except 进行捕获后,执行 finally 里的代码,并且继续往下执行。
自定义一个异常
单例模式的应用:
1.构造的过程非常复杂,消耗大量的资源,
2.这个类封装的数据可以作为整个应用的全局变量使用,一个类就够用了
__file__:此方法可以查看当前文件所在目录
__name__:在当前程序执行后显示__main__
Python2和Python3的区别:
Python2中,包需要 __init__.py 的文件才可以识别,Python3可以直接识别目录,通常习惯是都加
Python2中 __all__ 表示可以允许其他模块可以调用的方法,由于需要配合 from model import * 的导入方式来使用(Python3不建议这种导入方式),因此基本上不用了
查看模块的搜索路径:import sys sys.path
is 和 == :
is 是比较两个引用是否指向了同一个对象(引用的比较)
== 是比较两个对象是否相等(值的比较)
dir()方法可以查看此类都有哪些属性和方法,id()可以查看引用值
浅拷贝和深拷贝:
浅拷贝是在复制一份拷贝的引用的值,并不是将引用的值传递给拷贝对象,这样当被拷贝的引用值,发生变化时,由于浅拷贝在拷贝的时候对拷贝对象进行了复制,而不是原来的被拷贝对象,因此被拷贝对象发生变化时,浅拷贝的值不变,还是第一次浅拷贝复制被拷贝对象的时候的值
深拷贝在拷贝对象时,如果对象内含有其他引用的对象,会直接指向其他引用的内存地址,不同于浅拷贝的自己复制一份
Python中在属性前加两个下划线,来实现属性的私有化,其本质原理为:解释器在运行代码时,碰到前面加__的属性,会对其进行改名字,来实现隐藏,使用dir()来查看实例化后的对象会发现,私有化属性被改成 :_类名__属性名的形式 ,可以使用对象对其进行调用,即可获得私有化属性的值
_x:单前置下划线,私有化属性或方法,导入的时候到不进去
对私有化的属性进行访问:
设置setter和getter方法
简化:把setter和getter方法加到 obj = property(setter, getter)方法里 ,通过调用obj 实现set和get方法
在get方法上加@property,在set上加 @get_method_name.setter,一般是把属性名设置为方法名
生成器和列表:
生成器是调用一次算一次,不调用就不算,占用内存比较少
生成器的调用方式有两种,一种是next()方法,另一种是send()方法,send()方法在第一次调用的时候需要,传递空值None才可以
isinstance(obj, class)此方法判断第一个参数对象是否属于第二个类的类型
迭代器和可迭代对象:
可迭代对象:集合数据类型、生成器和带yield的函数
迭代器:可以被next()函数调用并且不断返回下一个值的对象,生成器也是迭代器。集合数据类型之类的就不算了,使用iter()方法可以把可迭代对象变成迭代器
在函数里使用方法locals()可以显示当前函数的属性名和属性值
使用dir(__builtin__)方法可以查看Python自带的全局属性和方法
闭包:
内部函数对外部函数作用域里变量的引用(非全局变量),则称内部函数为闭包
装饰器:
装饰器其实就是一个闭包,把一个函数当参数然后返回一个替代版函数
装饰器有两个特性:
一是可以把被装饰的函数,替换成其他函数,二是可以在加载模块的时候立即执行
变量名.__name__ 可以查看名字
写一个通用的装饰器,需要满足两点,1.不定长参数,2.有返回值。多练习,多应用
Python是动态语言:
为对象添加实例方法,导入types模块,调用MethodType()方法
魔法方法 __slots__ 是用来限制外部任意增加属性的功能,翻译为插槽,意思是给你几个特定的插槽可以用,没有的就不行
类装饰器:
在Python中只要在类里实现了魔法方法__call__()方法,都可以当函数用。例如:test = Test() 其中 t 是对象的引用,Test类实现了方法 __call__() 方法,那么可以这么调用:test() 表示的是调用的是Test类中的__call__()方法。如果需要把此类当做装饰器,需要先在__init__()方法中含有接收函数的形参,并且类中要实现__call__()方法,具体的函数调用在 __call__() 方法中
Python中的对象池:
Python中的对象池是提前内置在解释器中的,为了减少内存创建和删除的开销,对象池中一共有三种:
1.小整数范围是:[-5,257)、2.单个字符、3.一个连续的英文字符的合集(例如:hello、kjjkjhjeshkjhf,都是可以的),如果两个变量的值等于这三种中的随便一种,并且两个变量值相同,那么两个变量指向的是对象池中的同一个,内存地址相同
Python的内存管理机制(垃圾回收):
为新生成的对象分配内存
识别那些垃圾对象
从垃圾对象那回收内存
Python采用的是引用计数机制为主,标记-清除和分代收集两种机制为辅的策略
引用计数的优点 | 引用计数的缺点 |
简单 | 维护引用计数消耗资源 |
实时性:一旦没有了引用,内存就直接释放了。不用像其他机制等到特定的时机。实时性还带来一个好处:处理回收内存的时间分摊到了平时 | 循环引用 |
查看一个对象的引用计数可以导入sys模块,调用getrefcount()方法
gc模块无法处理子类重写了__del__() 方法的循环引用的回收,因此项目中要避免使用__del__()方法
内建属性:
属性访问拦截器:__getattribute__(),访问属性时,会回调此方法
消除装饰器的副作用(被装饰过的方法依然调用自身):导入functools模块,使用装饰器@functools.wraps(fun)来消除
上下文管理器:
任何实现了__enter__() 和 __exit__() 方法的对象,都可以成为上下文管理器,上下文管理器对象可以使用with关键字
assert 关键字的使用:
assert进行修饰的时候,表示在它出现出错的条件就会崩溃
assert 的语法格式:
assert expression
它的等价语句为:
if not expression:
raise AssertionError
使用下列代码来测试:
a = "hello"
加assert前
a == "hh"
False
加assert后,会报错
assert a == "hh"
Traceback (most recent call last):
File "<input>", line 1, in <module>
AssertionError
参考:https://blog.csdn.net/humanking7/article/details/45950781