当import moduleName
的时候,python是通过sys.path
来查找的。可以使用sys.path.append('newPath')
可以添加搜索路径。
当import了一个module之后,修改了module的代码,那么在当前运行时不会更新module修改后的功能。需要重新导入:
form imp import *
reload(moduleName)
==是判断两个对象值是否相等
is是判断两个是否指向同一个对象(引用比较)
浅拷贝:给变量赋值,只将自己的引用赋值给变量,没有赋值。
深拷贝:import copy b = copy.deepcopy(a)
import copy
b = copy.copy(a)
copy.copy指深拷贝本身变量的值,而不会深拷贝变量里面元素的值;而copy.deepcopy会深拷贝里面的值
copy.copy如果拷贝的是不可变类型,则是浅拷贝。
class Test(object):
def __init__(self):
self.__num = 100
def setNum(self, newNum):
print("----setter----")
self.__num = newNum
def getNum(self):
print("----getter----")
return self.__num
num = property(getNum, setNum)
#t.num = 200 #相当于调用了 t.setNum(200)
#print(t.num) #相当于调用了 t.getNum()
或者
class Test(object):
def __init__(self):
self.__num = 100
@property
def num(self):
print("----getter----")
return self.__num
@num.setter
def num(self, newNum):
print("----setter----")
self.__num = newNum
t = Test()
#t.num = 200 #相当于调用了 t.setNum(200)
#print(t.num) #相当于调用了 t.getNum()
可迭代对象Iterable
判断对象是否可以迭代
from collections import Iterable
isinstance(Obj,Iterable)
Iterator
from collections import Iterable
isinstance(Obj,Iterable)
iter()
函数,可以将可迭代对象转成迭代器。在函数内部定义一个函数,并且这个函数用到了外边函数的变量,那么将这个函数以及用到的一些变量称之为闭包。
def func(var):
def func_closure():
print(var*2)
return func_closure
f = func(123)
f()
原理:
def auth(func):
def inner():
print('验证权限...')
func()
return inner
def f1():
pass
def f2():
pass
f1 = auth(f1)
f1()
应用:语法糖简化调用
def auth(func):
print('装饰1...')
def inner():
print('验证权限1...')
func()
return inner
def auth2(func):
print('装饰2...')
def inner():
print('验证权限2...')
func()
return inner
@auth #相当于 f1 = auth(f1) ->注意装饰器的执行时间
@auth2
def f1():
pass
@auth
def f2():
pass
f1()
#@语法糖可以加多个
执行结果:
装饰2...
装饰1...
验证权限1...
验证权限2...
通用的的装饰器
def decorate(functionName):
def funcIn(*args,**kwargs):
ret = functionName(*args,**kwargs)
return ret
return funcIn
装饰器带参数
作用:在运行时起到有不同的功能。
def decorateArgs(pre="hello"):
def decorate(functionName):
def funcIn(*args,**kwargs):
ret = functionName(*args,**kwargs)
return ret
return funcIn
return decorate
@decorateArgs("bendeng")
def test():
pass
globals()
查看当前命名空间所有的全局变量。
localls()
查看当前命名空间所有的局部变量。
LEGB
原则:local->enclosing->global->buildins
dir(__buildin__)
查看所有内嵌
在运行时给对象(类)绑定(添加)属性(方法)。
class Test:
pass
def test(self):
pass
#动态添加属性可以直接添加
#动态添加方法使用types的MethodType方法
import types
t.test() = types.MethodType(test,t)#或者xxx = types.MethodType(test,t)
t.test()
静态方法和类方法直接添加
@staticmethod
def staticMethod():
pass
@classmethod
def classMethod():
pass
class Test:
pass
Test.test = staticMethod
Test.test = classMethod
__slots__
可以限制class实例能添加的属性
class Person:
__slots__ = ("name","age")
python中一边循环一边计算的机制,叫generator,生成器。
产生原因:生成列表时,如果很大(比如10000000),那么会占用很大的储存空间。根据列表生成规则只生成前面几个,就产生了生成器。
a = (x for x in range(10))
yield
的函数称为生成器def generator():
b = 0
for i in range(10):
yield b #next()一次就执行到这里停顿,b会更新值
b = i * 2
a = generator()
next(a) <==> a.__next__() #两种方式等价
for c in a: #生成器可以放在for循环里执行
pass
send:
def test():
i = 0
while i < 5:
temp = yield i
print(temp)
i += 1
t = test()
t.__next__() #temp 为None
t.send('hello') #temp为hello。send可以为temp赋值,相当于yield i的值为'hello'并赋值给temp
#第一次调用t.send(None)不会报错
yield作用:多任务。三种多任务方法之一:协程
。
def test1():
while True:
print('1')
yield None
def test2():
while True:
print('2')
yield None
t1 = test1()
t2 = test2()
while True:
t1.__next__()
t2.__next__()
intern
机制,共用对象,引用计数为0,则销毁。intern
机制,不共用对象,引用计数为0,销毁。python采用引用计数
为主,标记-清除
和分代收集
两种机制为辅的策略。
import sys
a = "hello world"
sys.getrefcount(a)
这里查看a对象的引用计数,会比正常计数大1。
gc.garbage
列表里面gc.collect()
会返回不可达的对象数目。在Python中,采用分代收集的方法。把对象分为三代,一开始,对象在创建的时候,放在一代中,如果在一次一代的检查中,该对象存活下来,就会被放到二代中,同理在一次二代的检查中,该对象存活下来,就会放到三代中。
gc模块唯一处理不了的是循环引用的类都有
__del__
方法,所以项目中尽量避免定义__del__
方法。
class Test(object):
def __init__(self,subject1):
self.subject1 = subject1
self.subject2 = 'python'
#属性访问拦截器
def __getattribute__(self,obj):
if(obj == 'subject1'):
print('access property subject1')
return 'back custom subject1 value'
else:
#return self.show() 发生递归调用,程序崩溃
return object.__getattribute__(self,obj)
def show(self):
pass
t = Test('p')
print(t.subject1)
print(t.subject2)
强调内容
不要在
__getattribute__
中调用self.xxxx。
输入dir(__buildin__)
可以看到很多python解释器启动后默认加载的属性和函数。
常用的内建函数:
m = map(lambda x:x*x,[1,2,3])
print(list(m)) #结果为[1,4,9]
f = filter(lambda x:x%2,[2,3])
print(list(f)) #结果为[3]
reduce(lambda x,y:x+y,[1,2,3,4])
在python3中,reduce函数从全局名字空间移除了,现在放置在functools模块里。
from functools import reduce
sorted([2,1,3,4]) #[1,2,3,4]
sorted([2,1,3,4],reverse=1) #[4,3,2,1]
集合与列表、元组类似,可以储存多个数据,但是这些数据是不重复的。
集合对象支持union(联合)、difference(差)和sysmmetric_difference(对称差集)等数学运算。
x = set([1,2,3,4]) #{1,2,3,4}
y = set([2,3,5,6,2]) #{2,3,5,6}
x & y #交集{2, 3}
x | y #并集{1, 2, 3, 4, 5, 6}
x ^ y #差集{1, 4, 5, 6}
functools是python2.5引入的。一些工具函数放在此包中。python3中增加了更多的函数,但很多不常用到。下面是常用的两个函数 :
particial
函数(偏函数):把一些函数的某些参数设置成默认值,返回一个新的函数,调用新函数会更简单。import functools
def showValue(*args,**kwargs):
print(args)
print(kwargs)
#p = showValue
#p(1,2,3)
p = functools.partial(showValue,1,2,3)
p() #(1, 2, 3) {}
p(id=123) #(1,2,3) {'id':123}
wraps
函数 __doc__
变化,对测试结果会有一些影响。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('test ~')
print(test.__name__) #wrapper
print(test.__doc__) #wrapper function
使用@functools.wraps(func)
后,print(test.__doc__)
会返回test function
。
import hashlib
m = hashlib.md5()
m.update('bendeng')
m.hexdigest() #45ac4274cad82274abcfce45f494eea4
常用的扩展库:
Python2中,python -m SimpleHTTPServer PORT
,python3中,python3 -m http.server PORT
。可运行起来静态服务, 用于预览和下载文件。
sudo apt-get install python-setuptools
2、安装模块
sudo easy_install xlrd
sudo easy_install xlwt
python -m pdb some.py
import pdb
pdb.run('testfun(args)')
import pdb
pdb.set_trace()
print
正则表达式是所有语言通用的字符串匹配方式。
python中使用正则表达式:
import re
#使用match方法进行匹配操作
result = re.match(正则表达式,要匹配的字符串)
#提取数据
result.group()
match
方法返回匹配对象Match Object
;否则返回None
。
\d = [0-9]
\D = [^0-9]
\w = [a-zA-Z0-9_]
\W = [^a-zA-Z0-9_]
* {0,}
+ {1,}
? {0,1}
Python中使用字符r表示字符使用原始字符。
re.match(r'.{3}\b','ben deng') #ben
re.match(r'.+\B','bendeng') #benden
匹配任意一个0-100的数字r'[1-9]\d?$|0$|100$'
或r'[1-9]?\d?$|100$'
分组匹配
r = re.match(r'(.*)(.*)','网页标题H2文本')
r.group|r.group(0) #'网页标题
H2文本
'
r.group(1) #网页标题
r.group(2) #H2文本
r.groups() #('网页标题', 'H2文本')
分组别名示例:
#coding=utf-8
import re
r = re.match(r'<(?P.+)>.*(?P=k1)><(?P.+)>.*(?P=k2)>' ,'h1文本
H2文本
')
print(r.groups()) #('h1','h2')
import re
re.search(r'h\d','h1文本
H2文本
')
# h1
import re
re.findall(r'h\d','h1文本
H2文本
')
#['h1', 'h1', 'h1', 'h2', 'h2']
import re
re.sub(r'h\d','m','h1文本
H2文本
')
#'m文本 H2文本 '
import re
re.split(r'<.+?>','h1文本
H2文本
')
#['', 'h1文本', '', 'H2文本', '']
正则表达式默认是贪婪模式,使用?使用非贪婪模式。