Python朝花夕拾
2015-08-20 09:40
447 查看
Q1:HTTPError403:Forbidden
python中经常使用urllib2.urlopen函数提取网页源码,但是有些时候这个函数返回的却是:HTTPError403:Forbidden,这表明源网站不允许爬虫进行爬取解决方法:伪装成浏览器进行访问
#!/usr/bin/envpython
#-*-coding:utf-8-*-
importurllib2
url="http://www.google.com/translate_a/t?client=t&sl=zh-CN&tl=en&q=%E7%94%B7%E5%AD%A9"
#浏览器头
headers={'User-Agent':'Mozilla/5.0(Windows;U;WindowsNT6.1;en-US;rv:1.9.1.6)Gecko/20091201Firefox/3.5.6'}
req=urllib2.Request(url=url,headers=headers)
data=urllib2.urlopen(req).read()
printdata
这样就可以得到网页源码了~
注:如果源码中中文为乱码,可以使用:
printdata.decode("UTF-8")
参见
Q2:文件读写
read()每次读取整个文件,它通常用于将文件内容放到一个字符串变量中,readline()和readlines()之间的差异是后者一次读取整个文件,像read()一样。readlines()自动将文件内容分析成一个行的列表,该列表可以由Python的for...in...结构进行处理。另一方面,readline()每次只读取一行,通常比readlines()慢得多。仅当没有足够内存可以一次读取整个文件时,才应该使用.readline()注意:f.readline()完成后最后一个字符是‘\n’,此时光标已经定位到了下一行的第0个位置,如果需要去除最后的回车键‘\n’,则为
line=f.readline()
line=line[:-1]
也可以用"string".strip('\n')
参见
forlineinopen('poem.txt'):
printline
f=open('test.txt','r')
#以读方式打开文件
forlineinf.readlines():
printline
逐行读取文件内容的三种方法
方法一: f=open("foo.txt")#返回一个文件对象 line=f.readline()#调用文件的readline()方法 whileline: printline,#后面跟','将忽略换行符 #print(line,end='') #在Python3中使用 line=f.readline() f.close() 方法二: 代码如下: forlineinopen("foo.txt"): printline,方法三: 代码如下: f=open("c:\\1.txt","r") lines=f.readlines()#读取全部内容 forlineinlines printline |
>>>>welcome_str[0]
'W'
>>>git_list=["qiwsir","github","io"]
>>>git_list[0]
'qiwsir'
Q3:list和str转化
list和str的最大区别是:list是原处可以改变的,str则原处不可变list和str转化
str.split()
“”.join(list)
>>>line="Hello.Iamqiwsir.Welcomeyou."
>>>line.split(".")
#以英文的句点为分隔符,得到list['Hello','Iamqiwsir','Welcomeyou','']
>>>line.split(".",1)
#这个1,就是表达了上文中的:Ifmaxsplitisgiven,atmostmaxsplitsplitsaredone.['Hello','Iamqiwsir.Welcomeyou.']
>>>name="AlbertAinstain"
#也有可能用空格来做为分隔符
>>>name.split("")['Albert','Ainstain']join可以说是split的逆运算
从list得到的字符串做切片操作
list[0][1:]#removethefirstcharacter
Q4:list对应元素相加
使用zip函数zip就是把2个数组糅在一起
x=[1,2,3,4,5]
y=[6,7,8,9,10]
zip(x,y)就得到了
[(1,6),(2,7),(3,8),(4,9),(5,10)]
list12=[x+yforx,yinzip(list1,list2)]
求l1=[[1,2],[3,4],[5,6]]对应元素的和
>>>l1=[[1,2],[3,4],[5,6]]
>>>list(map(sum,zip(*l1)))
[9,12]
zip参考:
对于将两个等长的列表合并成字典:dict(zip(list1,list2))
Q5:判断数据类型
importtypestype(x)istypes.IntType#判断是否int类型
type(x)istypes.StringType#是否string类型types.ListType==type(text)
Q6:三目运算符
true_partifconditionelsefalse_part>>>1ifTrueelse0
1
>>>1ifFalseelse0
0
Q7:list去重
http://www.jb51.net/article/55342.htmids=[1,4,3,3,4,2,3,4,5,6,1]
news_ids=list(set(ids))
news_ids.sort(ids.index)
Q8:Python的函数指针
#Icmp----GeneratessomeICMPtrafficdefmatchIcmp(json_data):
ifjson_data['network']['icmp']:
print'GeneratessomeICMPtraffic'
func_sets=[matchEntropy,matchIcmp,matchIrc,matchHttp,matchSmtp,matchDomain,matchFile,matchRegister,matchMutex,matchApi]
forfuncinfunc_sets:
func(json_data)
#模块中,类外的函数指针调用
defhwFunc1(x):
print("waleking'sfunc1")
defhwFunc2(x):
print("%s"%(x+1))
print("waleking'sfunc2")
funcSets={"func1":hwFunc1,"func2":hwFunc2}
funcSets["func1"](1)
Q9:TypeError:‘NoneType’objectisnotiterable
原因:最终所被调用的函数所返回的值,和返回值赋值给的变量,不匹配。Q10:Python按照书写顺序输出字典中的元素
使用dict时,Key是无序的。在对
dict做迭代时,我们无法确定Key的顺序。
如果要保持Key的顺序,可以用
OrderedDict:
>>>fromcollectionsimportOrderedDict >>>d=dict([('a',1),('b',2),('c',3)]) >>>d#dict的Key是无序的 {'a':1,'c':3,'b':2} >>>od=OrderedDict([('a',1),('b',2),('c',3)]) >>>od#OrderedDict的Key是有序的 OrderedDict([('a',1),('b',2),('c',3)])
注意,
OrderedDict的Key会按照插入的顺序排列,不是Key本身排序:
>>>od=OrderedDict() >>>od['z']=1 >>>od['y']=2 >>>od['x']=3 >>>od.keys()#按照插入的Key的顺序返回 ['z','y','x']
reference:
Q11:json相关
load(s):文件——>字典REPORT_PATH="/tmp/report.json"
method1:result1=json.load(open(REPORT_PATH))
method2:result2=json.loads(open(REPORT_PATH).read())
dump:字典——>文件
REPORT_PATH="/tmp/report.json"
results={“123”:345,“中文”:”内容”}
json.dump(results,report,ensure_ascii=False,sort_keys=False,indent=4,encoding=”utf-8”)
dumps:字典——>字符串
json.dumps(results,ensure_ascii=False,indent=4,encoding=”utf-8”))
注:涉及到中文的dump(s)务必加上ensure_ascii=False参数,否则会出现乱码问题
Q12:ERROR:Missingdependency:Nomodulenamedxxx
python将一个文件夹作为package对待,那么这个文件夹中必须包含一个名为__init__.py的文件,即使它是空的。即import文件夹名
如果sys.path.append()添加路径,则导入模块时会优先导入pip安装的模块,在查找sys.path.append添加的模块,如果同名,可能出现明明自己在模块中已经定义了但是搜索不到。
reference:
Q13:默认参数的坑
原因:Python函数在定义的时候,默认参数
L的值就被计算出来了,即
[],因为默认参数
L也是一个变量,它指向对象
[],每次调用该函数,如果改变了
L的内容,则下次调用时,默认参数的内容就变了,不再是函数定义时的
[]了。
所以,定义默认参数要牢记一点:默认参数必须指向不变对象!
要修改上面的例子,我们可以用
None这个不变对象来实现:
>>>add_end() ['END'] >>>add_end() ['END'] |
Q14:可变参数
defcalc(*numbers): sum=0 forninnumbers: sum=sum+n*n returnsum |
*号。在函数内部,参数
numbers接收到的是一个tuple,因此,函数代码完全不变。但是,调用该函数时,可以传入任意个参数,包括0个参数:
>>>calc(1,2) 5 >>>calc() 0 |
*号,把list或tuple的元素变成可变参数传进去
>>>nums=[1,2,3] >>>calc(*nums) 14 |
可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。而关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。请看示例:defperson(name,age,**kw): print'name:',name,'age:',age,'other:',kw 函数 person除了必选参数 name和 age外,还接受关键字参数 kw。在调用该函数时,可以只传入必选参数: >>>person('Michael',30) name:Michaelage:30other:{} 也可以传入任意个数的关键字参数: >>>person('Bob',35,city='Beijing') name:Bobage:35other:{'city':'Beijing'} >>>person('Adam',45,gender='M',job='Engineer') name:Adamage:45other:{'gender':'M','job':'Engineer'}[/code] >>>kw={'city':'Beijing','job':'Engineer'} >>>person('Jack',24,**kw) name:Jackage:24other:{'city':'Beijing','job':'Engineer'}[/code] >>>args=(1,2,3,4) >>>kw={'x':99} >>>func(*args,**kw) a=1b=2c=3args=(4,)kw={'x':99} |
普通递归: deffact(n): ifn==1: return1 returnn*fact(n-1) ===>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 使用递归函数需要注意防止栈溢出。在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。 尾递归:尾递归是指,在函数返回的时候,调用自身本身,并且,return语句不能包含表达式。这样,编译器或者解释器就可以把尾递归做优化,使递归本身无论调用多少次,都只占用一个栈帧,不会出现栈溢出的情况。 遗憾的是,大多数编程语言没有针对尾递归做优化,Python解释器也没有做优化,所以,即使把上面的[code]fact(n)函数改成尾递归方式,也会导致栈溢出。[/code] deffact_iter(num,product=1): ===>fact_iter(5,1) |
对于一个模块中,主脚本初始化logging之后,其他脚本可以通过log=logging.getLogger(__name__)来进行调用,此处有一个坑,就是需要在主脚本中设置log=logging.getLogger()而不能带有参数(默认是None),
1.logging对象其实是一个树形结构,每个创建的logging对象都是rootlogging对象的孩子结点。当使用logging模块的getLogger(name=None)函数构造logging对象的时候,如果name为None,这样会产生一个rootlogging对象。如果name中含有.,比如name='a.b.c',通过这种方式会产生3个logging对象,分别为c、b、a,c->b->a->root,root树的根结点,a为root的孩子结点,b为a的孩子结点,c为a的孩子结点,依次类推。
2.root结点是全局的,虽然这过程中涉及到多个模块,但是它们会共享一个root结点。
3.每个logging对象打LOG的时候,也会把LOG信息传递到传递到上层logging对象中,对于c->b->a->root这种情况,这个LOG其实会打4次,以c、b、a、root循序依次打一个LOG。
Q18:subprocess函数中shell问题
使用了shell=True这个参数。
这个时候,我们使用一整个字符串,而不是一个表来运行子进程。
Python将先运行一个shell,再用这个shell来解释这整个字符串。
rc=subprocess.call(["ls","-l"])
out=subprocess.call("ls-l",shell=True)
argsisrequiredforallcallsandshouldbeastring,orasequenceofprogramarguments.Providingasequenceofargumentsisgenerallypreferred,asitallowsthemoduletotakecareofanyrequiredescapingandquotingofarguments(e.g.topermitspacesinfilenames).Ifpassingasinglestring,eithershellmustbe
True(seebelow)orelsethestringmustsimplynametheprogramtobeexecutedwithoutspecifyinganyarguments.
尽量不用带shell的函数
Q19:遍历列表统计每个单词出现的个数,返回字典,key为单词,value为对应的次数
最low的方法:
dict_api={}
forapiinapis:
ifapiindict_api:
dict_api[api]+=1
else:
dict_api[api]=1
优雅的方法:
l=['a','a','c','b','c']
dict((k,l.count(k))forkinset(l))
第三方库:
fromcollectionsimportCounter
dict(Counter(l))
Counter相关,
Counter实际上也是
dict的一个子类:
创建
>>>c=Counter()#创建一个空的Counter类
>>>c=Counter('gallahad')#从一个可iterable对象(list、tuple、dict、字符串等)创建
>>>c=Counter({'a':4,'b':2})#从一个字典对象创建
>>>c=Counter(a=4,b=2)#从一组键值对创建
当所访问的键不存在时,返回0,而不是KeyError;否则返回它的计数。
>>>c=Counter("abcdefgab")
>>>c["a"]
2
>>>c["c"]
1
>>>c["h"]
0
计数器的更新(update和subtract)
reference:字典按value排序:
sorted_api=sorted(dict_api.iteritems(),key=lambdad:d[1],reverse=True)
返回列表
字典合并:
相关文章推荐
- Python字符串类型转换函数
- 详解Python3中yield生成器的用法
- python中执行命令的3种方法小结
- Python编程服务
- Python笔记:protocol buffer使用
- 详解Python3中yield生成器的用法
- 使用Python3编写抓取网页和只抓网页图片的脚本
- 使用Python求解最大公约数的实现方法
- Python中列表和元组的相关语句和方法讲解
- Python3字符串学习教程
- Python中字典映射类型的学习教程
- 在类Unix系统上开始Python3编程入门
- 关于python3中写入csv文件多余空行
- wxPython Cookbook(Chatper2)Part 1
- python yield 实例理解要点
- Python & OpenCV混合编程
- Python 中 logging 日志模块在多进程环境下的使用
- python集成开发eclipse环境安装
- 使用 Python 为 KVM 编写脚本,第 1 部分: libvirt
- Ubuntu下python3 安装 pip 和 Django