python进阶篇
python进阶篇
import 导入模块
sys.path:获取指定模块搜索路径的字符串集合,可以将写好的模块放在得到的某个路径下,就可以在程序中import时正确找到。
import sys
sys.path.append("")
重新导入模块
reload(模块)
==、is
a = [11,22,33]
b = [11,22,33]
>>>a == b
True
>>>a is b
False
>>>a = c
>>>a is c
True
数字在一定范围内a is b,True,其他范围False
深拷贝和浅拷贝
a = [11,22,33]
b =a
>>>id(a)==id(b)
True
没有复制数据,只是把指向的位置复制给它就是浅拷贝
import copy
c = copy.deepcopy(a)
id(a)和id(c)不同,深拷贝
a = [11,22,33]
b = [44,55,66]
c = [a,b]
d = copy.deepcopy(c)
e = copy.copy(c)
a.append(44)
>>>c[0]
[11,22,33,44]
>>>d[0]
[11,22,33]
>>>e[0]
[11,22,33,44]
**copy.copy()列表后,id 也不同,但是会持续拷贝 **
改为元组后,copy.copy(),id相同,元组不可变类型,直接浅拷贝
copy.copy()根据可变不可变类型,功能不同
十进制,二进制,八进制,十六进制之间的转换
私有化
-
xx:公有变量
-
_x:from somemodule import * 禁止导入,类对象和子类可以访问
-
__xx:双前置下划线,避免与子类中的属性命名冲突,无法在外部直接访问
-
___xx___:双前后下划线,对象或属性
-
xx_:单后置下划线,用于避免与python关键字的冲突
1.私有属性添加getter和setter方法
class Money(object): def __init__(self): self.__money = 0 def getMoney(self): return self.__money def setMoney(self,value): if isinstance(value,int): self.__money = value else: print("error:不是整型数字")
2.使用property升级getter和setter方法
class Money(object): def __init__(self): self.__money = 0 def getMoney(self): return self.__money def setMoney(self,value): if isinstance(value,int): self.__money = value else: print("error:不是整型数字") money = property(getMoney,setMoney)
注意:
-
t.num到底是调用getNum()还是setNum(),要根据实际场景来判断;
-
如果是给t.num赋值,那么一定是调用setNum()
-
如果是获取t.num的值,那么就一定调用getNum()
-
property的作用:相当于把方法进行了封装,开发者在对属性设置数据的时候更方便
class Money(object): def __init__(self): self.__money = 0 @property def money(self): return self.__money @money.setter def money(self,value): if isinstance(value,int): self.__money = value else: print("error:不是整型数字")
迭代器
1.可迭代对象
直接作用于for循环的数据类型有以下几种:
一种是集合数据类型,如list,tuple,dict,set,str等;
一种是generator,包括生成器和带yield的generator function。
这些可以直接作用于for循环的对象统称为可迭代对象:lterable。
2.判断是否可以迭代
可以使用isinstance()判断一个对象是否是lterable:
from collections import Iterable isinstance("abc",Iterable) >>>True
3.迭代器
可以被next()函数调用并不断返回下一值的对象成为迭代器:Iterator
from collections import Iterator
isinstance([],Iterator)
>>>False
isinstance((x for x in range(10)),Iterator)
>>>True
4.iter()函数
生成器都是Iterator对象,但list、dict、str虽然是Iterable,却不是Iterator。
把list、dict、str等Iterable变成Iterator可以使用iter()函数:
isinstance(iter([]),Iterator)
>>>True
闭包
#在函数内部再定义一个函数,并且这个函数用到了外边函数的变量,那么将这个函数以及用到的一些变量称之为闭包 def test(number): print("----1------") def test_in(number2): print("------2----") print(number-number2) print("-----3-----") return test_in ret = test(100) ret(1) \>>>----1------ -----3----- ------2---- 99 def test(a,b): def test_in(x): print(a*x+b) return test_in line1 = test(1,1) line1(0) line2 = test(10,4) line2(0) line1(0)
装饰器
def w1(func):
def inner():
print("----正在验证权限------")
func()
return inner
def f1():
print("----f1-----")
def f2():
print("----f2-----")
innerFunc = w1(f1)
innerFunc()
f1 赋值地址,f1()调用函数
def w1(func):
def inner():
print("----正在验证权限------")
func()
return inner
def f1():
print("----f1-----")
def f2():
print("----f2-----")
f1 = w1(f1)
f1()
@w1等价于w1(f1)
def w1(func):
def inner():
print("----正在验证权限------")
func()
return inner
@w1
def f1():
print("----f1-----")
@w1
def f2():
print("----f2-----")
f1()
f2()
多个装饰器
def makeBold(fn):
def wrapped():
print("----1------")
return "" + fn() + ""
return wrapped
def makeItalic(fn):
def wrapped():
print("----2------")
return "" + fn() +""
return wrapped
@makeBold#只要python解释器执行到了这个代码,那么就会自动进行装饰,而不是等到调用才装饰的
@makeItalic
def test3():
print("--------3-----")
return "hello world-3"
ret = test3()
print(ret)
>>>----1------
----2------
--------3-----
hello world-3
从上往下执行,从下往上装饰
def w1(func):
print("----正在装饰1-----")
def inner():
print("------正在验证权限1-----")
def w2(func):
print("---- 正在装饰2-----")
def inner():
print("----正在验证权限2----")
func()
return inner()
@w1
@w2
def f1():
print("----f1----")
f1() #在调用f1之前,已经进行装饰了
>>>---- 正在装饰2-----
----正在装饰1-----
------正在验证权限1-----
----正在验证权限2----
----f1----
装饰器对有参数,无参数函数进行装饰
def func(functionName): print("----func---1---") def fun_in(*args,**kwargs):#定义不定长参数 print("---func_in---1---") functionName(*args,**kwargs) print("---func_in---2---") print("---func---2---") return func_in @func def test1(a,b,c): print("----test-a=%d,b=%d,c=%d---"%(a,b,c)) @func def test2(a,b,c,d): print("----test-a=%d,b=%d,c=%d,d=%d---"%(a,b,c,d)) test1(11,22,33) test2(44,55,66,77) \>>>----func---1--- ---func---2--- ---func---1--- ---func---2--- ---func_in---1--- ----test-a=11,b=22,c=33--- ---func_in---2--- ---func_in---1--- ----test-a=44,b=55,c=66,d=77--- ---func_in---2---
装饰器对带有返回值的参数进行装饰
def func(functionName): print("---func---1---") def func_in(): print("---func_in---1---") ret = functionName()#保存返回来的haha print("---func_in---2---") return ret #把haha返回到调用处 print("---func---2---") @func def test(): print("----test----") return "haha" ret = test() print("test return value is %s"%ret) 带有参数的装饰器 def func_arg(arg): def func(functionName): def func_in(): print("---记录日志-arg=%s--"%arg) if arg =="heihei": functionName() functionName() else: functionName() return func_in() return func @func_arg("heihei")#带有参数的装饰器,能够起到在运行时,有不同的功能 def test(): print("--test--") @func_arg("haha") def test2(): print("--test2--") test() test2()
作用域
LEGB规则
locals -> enclosing function -> globals -> builtings
locals:当前所在命名空间
enclosing function:外部嵌套函数的命名空间(闭包中常见)
globals:全局变量
builtings:内嵌
动态添加属性和方法
添加属性 类/实例.属性 = XX
添加方法 不能按上面方法,
import types.MethodType
绑定的对象.函数名() = types.MethodType(函数名,绑定的对象)
_slots_
为了达到限制的目的,Python允许在定义class的时候,定义一个特殊的__slots__变量来限制class实例能添加的属性:
>>>class Person(object): __slots__ = ("name","age") >>>P = Person() >>>P.name = "老王" >>>P.age = 20 #添加其他属性会报错
生成器
一边循环一边计算
创建生成器方法
1.把列表生成式的[]改成(),通过next函数获取生成器的下一个返回值
def creatNum(): print("-----start-----") a,b = 0,1 for i in range(5): print("----1----") yield b #程序停下来,把yield后面的值返回 print("----2----") a,b = b,a+b print("----3----") print("----stop----") \>>>a = creatNum() \>>>a <generator object creatNum at 0x7f42d27de7d8> \>>>next(a) -----start----- ----1---- 1 \>>>next(a)#等价于a.__next__() ----2---- ----3---- ----1---- 1
def test(): i = 0 while i<5: temp = yield i print(temp) i+=1 \>>>t = test() \>>>t.__next__() [out] 0 \>>>t.__next__() None [out] 1 \>>>t.__next__() None [out] 2 \>>>t.send("haha") haha [out] 3
类当作装饰器
定义一个__call__方法,类就可以直接调用
-
class Test(object):
def __init__(self,func):
print("---初始化---")
print("func name is %s"%func.__name__)
self.__func = func
def __call__(self):
print("---装饰器中的功能---")
self.__func()
@Test
def test():#当用Test来装作装饰器对test函数进行装饰的时候,首先会创建一个Test的实例对象,func指向test(),func.__name__函数名
print("---test---")
test()
元类
类也是一个对象
使用type创建类
type(类名,由父类名称组成的元组(针对继承的情况可以为空),包含属性的字典)
Person = type("Person",(),{"num":0})
p1 = Person()
\>>>p1.num
0
def printNum(self):
print("---num-%d---"%self.num)
\>>>Test3 = type("Test3",(),{"printNum":printnum})
t1 = Test3()
t1.num = 100
t1.printNum()
---num-100---
__metaclass__属性
def upper_attr(future_class_name,future_class_parents,future_class_attr):
#遍历属性字典,把不是__开头的属性名字变为大写
newAttr = {}
for name,value in future_class_attr.items():
if not name.startswith("__"):
newAttr[name.upper()] = value
#调用type来创建一个类
return type(future_class_name,future_class_parents,newAttr)
class Foo(object,metaclass = upper_attr):
#设置Foo类的元类为upper_attr
bar = "bip"
print(hasattr(Foo,'bar'))
print(hasattr(Foo,'BAR'))
f = Foo()
print(f.BAR)
垃圾回收
1.小整数对象池
[-5,257)这些整数对象是提前建立好的,不会被垃圾回收。在一个python程序中,所有位于这个范围内的整数使用的都是同一个对象
2.大整数对象池
3.intern机制
- 小整数共用对象,常驻内存
- 单个字符共用对象,常驻内存
- 单个单词,不可修改,默认开启intern机制,共用对象,引用计数为0,则销毁
Garbage collection(GC垃圾回收)
python采用的是引用计数机制为主,标记-清除和分代收集两种机制为辅的 策略
引用计数机制的优点:
- 简单
- 实用性:一旦没有引用,内存就直接释放了。处理回收内存的时间分摊到了平时
缺点:
-
维护引用计数消耗资源
-
循环引用
list1 = [] list2 = [] list1.append(list2) list2.append(list1)
相互引用,list1与list2的引用计数也仍然为1,所占用的内存永远无法被回收。
链表引用计数,分代收集
1.引用计数+1的情况
- 对象被创建,例如a=23
- 对象被引用,例如b =a
- 对象被作为参数,传入到一个函数中,例如func(a)
- 对象作为一个元素,存储在容器中,例如list1=[a,a]
2.引用计数-1的情况
- 对象的别名被显式销毁,例如del a
- 对象的别名被赋予新的对象,例如a=24
- 一个对象离开他的作用域,例如func函数执行完毕时,func函数中的局部变量(全局变量不会)
- 对象所在的容器被销毁,或从容器中删除对象
3.查看一个对象的引用计数
import sys a = "hello world" sys.getrefcount(a) \>>>2
import gc#gc默认运行 gc.disable()#关闭gc gc.collect()#手动调用collect
内建属性
常用专有属性 说明 触法方式 _init_ 构造初始化函数 创建实例后,赋值时使用,在__new__后 _new_ 生成实例所需属性 创建实例时 _class_ 实例所在的类 实例._class_ _str_ 实例字符串表示,可读性 print(类属性),如没实现,使用repr结果 _repr_ 实例字符串表示,准确性 类实例 回车 或者print(repr(类实例)) _del_ 析构 del删除实例 _dict_ 实例自定义属性 vars(实例._dict_) _doc_ 类文档,子类不能继承 help(类或实例) _getattribute_ 属性访问拦截器 访问实例属性时 _base_ 类的所有父类构成元素 类名._bases_ 内建函数
map函数
map(function,sequence[,sequence,...]) -> list
- function:是一个函数
- sequence:是一个或多个序列,取决于function需要几个参数
- 返回值是一个list
#函数需要一个参数 map(lambda x:x*x,[1,2,3]) # 结果为:[1,4,9] #函数需要两个参数 map(lambda x, y: x+y,[1,2,3],[4,5,6]) #结果为:[5,7,9] def f1(x, y): return (x,y) l1 =[0,1,2,3,4,5,6] l2 =['Sun','M','T','W','T','F','S'] l3 =map(f1,l1,l2) print(list(l3)) #结果为:[(0,'Sun'),(1,'M'),(2,'T'),(3,'W'),(4,'T'),(5,'F'),(6,'S')]
filter函数
对指定对象执行过滤
filter函数会对序列参数sequence中的每个元素调用function函数,最后返回的结果包含调用结果为Ture的元素。
返回值的类型和参数sequence的类型相同
filter(lambda x: x%2,[1,2,3,4]) [1,3] filter(None,"she") 'she'
reduce函数
reduce依次从sequence中取一个元素,和上一次调用function的结果做参数再次调用function。第一次调用function时,如果提供initial参数,会以sequence中的第一个元素和initial作为参数调用function,否则会以序列sequence中的前两个元素做参数调用function.注意function函数不能为None。
reduce(lambda x, y: x+y,[1,2,3,4]) 10 reduce(lambda x,y:x+y,[1,2,3,4],5) 15 reduce(lambda x, y:x+y,['aa','bb','cc'],'dd') 'ddaabbcc' python3里面reduce函数要先引入:from functools import reduce
sorted函数
a = [55,22,77,99] a.sort() \>>>a [22,55,77,99] a.sort(reverse=Ture) \>>>a [99,77,55,22] sorted([1,5,4,2]) \>>>[1,2,4,5] sorted([1,5,4,2],reverse=1) \>>>[5,4,2,1]
集合set
a=[11,55,44,22,11,11] b = set(a) \>>>b {11,55,44,22} \>>>a=list(b) \>>>a [11,55,44,22] a = "abcdef" b = set(a) \>>>b {'a','b','c','d','e','f'} A="bdfhuy" B = set(A) \>>>B {'b','d','f','h','u','y'} \>>>b&B {'b','d','f'} \>>>b|B {'a','b','c','d','e','f,'h','u','y'} \>>>b-B {'a','c','e'} \>>>b^B {'a','c','e','h','u','y'}
functools
partial函数
import functools def showarg(*args,**kw): print(arg) print(kw) p1=functools.partial(showarg,1,2,3) p1() p1(4,5,6) p1(a='python',b='itcast') \>>>(1,2,3) {} (1,2,3,4,5,6) {} (1,2,3) {'a':'python','b':'itcast'}
wraps函数
使用装饰器时,被装饰后的函数其实已经是另外一个函数(函数名等函数属性会发生改变,functools包中提供了叫warps的装饰器来消除这样的副作用。
import functools
def note(func):
"note function"
@functools.wraps(func)
def wrapper():
"wrapper function"
print('note something')
return func()
return wrapper
@note
def test():
"test function"
print('I am test')
test()
print(test.__doc__)
模块
hashlib加密算法
import hashlib
m = hashlib.md5()#创建hash对象,md5
print m
m.update('itcast')#更新哈希对象以字符串参数
print(m.hexdigest())#返回十六进制数字字符串