配色: 字号:
python字符串的使用详解
2016-09-24 | 阅:  转:  |  分享 
  
python字符串的使用详解

之前在网上看了关于python最基础的一些教程,看着都通俗易懂,但是在写的过程中却感觉还是很生涩。关于字符串的使用还是应该多写多练!







思路就是:以“#”为分割符,取左边的"teacher_id=123"([0]代表第一个索引位置),接着去除两边的空格(使用strip()),然后在以“=”为分割符,取“teacher_id"并去除两边的空格,打印出来的结果就是类似于”teacher_id:123"





去空格及特殊符号

s.strip().lstrip().rstrip('','')

复制字符串

#strcpy(sStr1,sStr2)

sStr1=''strcpy''

sStr2=sStr1

sStr1=''strcpy2''

printsStr2

连接字符串

#strcat(sStr1,sStr2)

sStr1=''strcat''

sStr2=''append''

sStr1+=sStr2

printsStr1

查找字符

#strchr(sStr1,sStr2)

#<0为未找到

sStr1=''strchr''

sStr2=''s''

nPos=sStr1.index(sStr2)

printnPos

比较字符串

#strcmp(sStr1,sStr2)

sStr1=''strchr''

sStr2=''strch''

printcmp(sStr1,sStr2)

扫描字符串是否包含指定的字符

#strspn(sStr1,sStr2)

sStr1=''12345678''

sStr2=''456''

#sStr1andcharsbothinsStr1andsStr2

printlen(sStr1andsStr2)

字符串长度

#strlen(sStr1)

sStr1=''strlen''

printlen(sStr1)

将字符串中的大小写转换

#strlwr(sStr1)

sStr1=''JCstrlwr''

sStr1=sStr1.upper()

#sStr1=sStr1.lower()

printsStr1

追加指定长度的字符串

#strncat(sStr1,sStr2,n)

sStr1=''12345''

sStr2=''abcdef''

n=3

sStr1+=sStr2[0:n]

printsStr1

字符串指定长度比较

#strncmp(sStr1,sStr2,n)

sStr1=''12345''

sStr2=''123bc''

n=3

printcmp(sStr1[0:n],sStr2[0:n])

复制指定长度的字符

#strncpy(sStr1,sStr2,n)

sStr1=''''

sStr2=''12345''

n=3

sStr1=sStr2[0:n]

printsStr1

将字符串前n个字符替换为指定的字符

#strnset(sStr1,ch,n)

sStr1=''12345''

ch=''r''

n=3

sStr1=nch+sStr1[3:]

printsStr1

扫描字符串

#strpbrk(sStr1,sStr2)

sStr1=''cekjgdklab''

sStr2=''gka''

nPos=-1

forcinsStr1:

ifcinsStr2:

nPos=sStr1.index(c)

break

printnPos

翻转字符串

#strrev(sStr1)

sStr1=''abcdefg''

sStr1=sStr1[::-1]

printsStr1

查找字符串

#strstr(sStr1,sStr2)

sStr1=''abcdefg''

sStr2=''cde''

printsStr1.find(sStr2)

分割字符串

#strtok(sStr1,sStr2)

sStr1=''ab,cde,fgh,ijk''

sStr2='',''

sStr1=sStr1[sStr1.find(sStr2)+1:]

printsStr1

#或者

s=''ab,cde,fgh,ijk''

print(s.split('',''))

连接字符串

delimiter='',''

mylist=[''Brazil'',''Russia'',''India'',''China'']

printdelimiter.join(mylist)

PHP中addslashes的实现

defaddslashes(s):

d={''"'':''\\"'',"''":"\\''","\0":"\\\0","\\":"\\\\"}

return''''.join(d.get(c,c)forcins)



s="John''Johny''Doe(a.k.a.\"SuperJoe\")\\\0"

prints

printaddslashes(s)

只显示字母与数字

defOnlyCharNum(s,oth=''''):

s2=s.lower();

fomart=''abcdefghijklmnopqrstuvwxyz0123456789''

forcins2:

ifnotcinfomart:

s=s.replace(c,'''');

returns;



print(OnlyStr("a000aa-b"))



截取字符串

str=’0123456789′

printstr[0:3]#截取第一位到第三位的字符

printstr[:]#截取字符串的全部字符

printstr[6:]#截取第七个字符到结尾

printstr[:-3]#截取从头开始到倒数第三个字符之前

printstr[2]#截取第三个字符

printstr[-1]#截取倒数第一个字符

printstr[::-1]#创造一个与原字符串顺序相反的字符串

printstr[-3:-1]#截取倒数第三位与倒数第一位之前的字符

printstr[-3:]#截取倒数第三位到结尾

printstr[:-5:-3]#逆序截取,具体啥意思没搞明白?

常用的字符串操作汇总如下:

①去除空格以及一些特殊符号(’#‘,’,‘,’|''等):

删除字符串两边的空格:str.strip()

删除字符串末尾的空格:str.lstrip()

删除字符串左边的空格:str.rstrip()

②字符串分割(默认为空白字符):

str.split()

③字符串查找:

str.find()#返回的是索引位置

④计算字符串长度:

len(str)

⑤字符串大小写:

str.upper()#字母大写

str.lower()#字母小写

str.capitalize()#首字母大写

str.istitle()#是否是首字母大写的

str.isupper()#字母是否便是大写

str.islower()#字母是否全是小写

用python也差不多一年多了,python应用最多的场景还是web快速开发、爬虫、自动化运维:写过简单网站、写过自动发帖脚本、写过收发邮件脚本、写过简单验证码识别脚本。

爬虫在开发过程中也有很多复用的过程,这里总结一下,以后也能省些事情。

1、基本抓取网页

get方法



importurllib2

url"http://www.baidu.com"

respons=urllib2.urlopen(url)

printresponse.read()



post方法



importurllib

importurllib2



url="http://abcde.com"

form={''name'':''abc'',''password'':''1234''}

form_data=urllib.urlencode(form)

request=urllib2.Request(url,form_data)

response=urllib2.urlopen(request)

printresponse.read()

2、使用代理IP

在开发爬虫过程中经常会遇到IP被封掉的情况,这时就需要用到代理IP;

在urllib2包中有ProxyHandler类,通过此类可以设置代理访问网页,如下代码片段:

importurllib2



proxy=urllib2.ProxyHandler({''http'':''127.0.0.1:8087''})

opener=urllib2.build_opener(proxy)

urllib2.install_opener(opener)

response=urllib2.urlopen(''http://www.baidu.com'')

printresponse.read()

3、Cookies处理

cookies是某些网站为了辨别用户身份、进行session跟踪而储存在用户本地终端上的数据(通常经过加密),python提供了cookielib模块用于处理cookies,cookielib模块的主要作用是提供可存储cookie的对象,以便于与urllib2模块配合使用来访问Internet资源.

代码片段:

importurllib2,cookielib



cookie_support=urllib2.HTTPCookieProcessor(cookielib.CookieJar())

opener=urllib2.build_opener(cookie_support)

urllib2.install_opener(opener)content=urllib2.urlopen(''http://XXXX'').read(www.zycaihui.com)

关键在于CookieJar(),它用于管理HTTPcookie值、存储HTTP请求生成的cookie、向传出的HTTP请求添加cookie的对象。整个cookie都存储在内存中,对CookieJar实例进行垃圾回收后cookie也将丢失,所有过程都不需要单独去操作。

手动添加cookie

cookie="PHPSESSID=91rurfqm2329bopnosfu4fvmu7;kmsign=55d2c12c9b1e3;KMUID=b6Ejc1XSwPq9o756AxnBAg="

request.add_header("Cookie",cookie)

4、伪装成浏览器

某些网站反感爬虫的到访,于是对爬虫一律拒绝请求。所以用urllib2直接访问网站经常会出现HTTPError403:Forbidden的情况

对有些header要特别留意,Server端会针对这些header做检查

User-Agent有些Server或Proxy会检查该值,用来判断是否是浏览器发起的Request

Content-Type在使用REST接口时,Server会检查该值,用来确定HTTPBody中的内容该怎样解析。

这时可以通过修改http包中的header来实现,代码片段如下:

importurllib2



headers={

''User-Agent'':''Mozilla/5.0(Windows;U;WindowsNT6.1;en-US;rv:1.9.1.6)Gecko/20091201Firefox/3.5.6''

}

request=urllib2.Request(

url=''http://my.oschina.net/jhao104/blog?catalog=3463517'',

headers=headers

)

printurllib2.urlopen(request).read()

5、页面解析

对于页面解析最强大的当然是正则表达式,这个对于不同网站不同的使用者都不一样,就不用过多的说明,附两个比较好的网址:

正则表达式入门

正则表达式在线测试

其次就是解析库了,常用的有两个lxml和BeautifulSoup,对于这两个的使用介绍两个比较好的网站:

lxml

BeautifulSoup

对于这两个库,我的评价是,都是HTML/XML的处理库,Beautifulsoup纯python实现,效率低,但是功能实用,比如能用通过结果搜索获得某个HTML节点的源码;lxmlC语言编码,高效,支持Xpath

6、验证码的处理

对于一些简单的验证码,可以进行简单的识别。本人也只进行过一些简单的验证码识别。但是有些反人类的验证码,比如12306,可以通过打码平台进行人工打码,当然这是要付费的。

7、gzip压缩

有没有遇到过某些网页,不论怎么转码都是一团乱码。哈哈,那说明你还不知道许多web服务具有发送压缩数据的能力,这可以将网络线路上传输的大量数据消减60%以上。这尤其适用于XMLweb服务,因为XML数据的压缩率可以很高。

但是一般服务器不会为你发送压缩数据,除非你告诉服务器你可以处理压缩数据。

于是需要这样修改代码:

importurllib2,httplibrequest=urllib2.Request(''http://xxxx.www.edu800.cncom'')

request.add_header(''Accept-encoding'',''gzip'')1

opener=urllib2.build_opener()

f=opener.open(request)

这是关键:创建Request对象,添加一个Accept-encoding头信息告诉服务器你能接受gzip压缩数据

然后就是解压缩数据:

importStringIO

importgzip



compresseddata=f.read()

compressedstream=StringIO.StringIO(compresseddata)

gzipper=gzip.GzipFile(fileobj=compressedstream)

printgzipper.read()

8、多线程并发抓取

单线程太慢的话,就需要多线程了,这里给个简单的线程池模板这个程序只是简单地打印了1-10,但是可以看出是并发的。

虽然说python的多线程很鸡肋,但是对于爬虫这种网络频繁型,还是能一定程度提高效率的。

fromthreadingimportThread

fromQueueimportQueue

fromtimeimportsleep

#q是任务队列

#NUM是并发线程总数

#JOBS是有多少任务

q=Queue()

NUM=2

JOBS=10

#具体的处理函数,负责处理单个任务

defdo_somthing_using(arguments):

printarguments

#这个是工作进程,负责不断从队列取数据并处理

defworking():

whileTrue:

arguments=q.get()

do_somthing_using(arguments)

sleep(1)

q.task_done()

#forkNUM个线程等待队列

foriinrange(NUM):

t=Thread(target=working)

t.setDaemon(True)

t.start()

#把JOBS排入队列

foriinrange(JOBS):

q.put(i)

#等待所有JOBS完成

q.join()

第一形式

#!/usr/bin/envpython

#coding=utf-8

classPerson(object):#object表示继承自object类,Python3中可省略次内容

"""

ThisisasampleofClass

"""

breast=90#类的属性是静态变量



def__init__(self,name):#初始化方法self为对象实例本身

self.name=name



defget_name(self):#类的方法

returnself.name



defcolor(self,color):

d={}

d[self.name]=color;

returnd



if__name__=="__main__":

girl=Person("songjia")

printgirl.name

girl.name="liu"

printgirl.get_name()

printgirl.color("white")

girl.breast=80#修改实例的属性

printgirl.breast

printPerson.breast#类属性不会随实例属性的改变而改变

Person.breast=100

printPerson.breast

printgirl.breast

第二种形式

>>>__metaclass__=type

>>>classCC:

...pass

...

>>>cc=CC()

>>>cc.__class__



>>>type(cc)



实例

girl=Person("songjia")

类属性

>>>classA(object):#Python3:classA:

...x=7#类的属性

...

下面列出类的几种特殊属性的含义:

C.__name__:以字符串的形式,返回类的名字,注意这时候得到的仅仅是一个字符串,它不是一个类对象

C.__doc__:显示类的文档

C.__base__:类C的所有父类。如果是按照上面方式定义的类,应该显示object,因为以上所有类都继承了它。等到学习了“继承”,再来看这个属性,内容就丰富了

C.__dict__:以字典形式显示类的所有属性

C.__module__:类所在的模块

实例属性

>>>classA(object):#Python3:classA:

...x=7#类的属性

...

>>>foo=A()

>>>foo.x#实例属性

类中变量引用可变数据

>>>classB(object):

...y=[1,2,3]



>>>B.y#类属性

[1,2,3]

>>>bar=B()

>>>bar.y#实例属性

[1,2,3]

>>>bar.y.append(4)

>>>bar.y

[1,2,3,4]

>>>B.y

[1,2,3,4]

>>>B.y.append("aa")

>>>B.y

[1,2,3,4,''aa'']

>>>bar.y

[1,2,3,4,''aa'']

当类中变量引用的是可变对象是,类属性和实例属性都能直接修改这个对象,从而影响另一方的值。

访问限制

#!/usr/bin/envpython

#coding=utf-8

classPerson(object):

"""

ThisisasampleofClass

"""



def__init__(self,name):#初始化方法self为对象实例本身

self.__name=name#__xx双下划线表示类的私有变量



defget_name(self):#类的方法

returnself.__name#类的内部可以访问



if__name__=="__main__":

girl=Person("songjia")

printgirl.get_name()

printgirl._name#无法访问类的私有变量

文档字符串

在函数、类或者文件开头的部分写文档字符串说明,一般采用三重引号。这样写的最大好处是能够用help()函数看。

"""Thisispythonlesson"""

defstart_func(arg):

"""Thisisafunction."""

pass

classMyClass:

"""Thisismyclass."""

defmy_method(self,arg):

"""Thisismymethod."""

pass

继承

单继承

#!/usr/bin/envpython

#coding=utf-8

classPerson(object):#Python3:classPerson:

def__init__(self,name):

self.name=name



defheight(self,m):

h=dict((["height",m],))

returnh

defbreast(self,n):

b=dict((["breast",n],))

returnb

classGirl(Person):#继承

defget_name(self):

returnself.name

if__name__=="__main__":

cang=Girl("liuguoquan")

printcang.get_name()#Python3:print(cang.get_name()),下同,从略

printcang.height(160)

printcang.breast(90)

调用覆盖的方法

classGirl(Person):

def__init__(self,name):

#Person.__init__(self,name)#调用父类的方法

super(Girl,self).__init__(name)#调用父类的方法常用写法

self.real_name="Aoisola"

defget_name(self):

returnself.name



if__name__=="__main__":

cang=Girl("canglaoshi")

printcang.real_name

printcang.get_name()

printcang.height(160)

printcang.breast(90)

执行结果为:

Aoisola

canglaoshi

{''height'':160}

{''breast'':90}

多继承

#!/usr/bin/envpython

#coding=utf-8

classPerson(object):#Python3:classPerson:

defeye(self):

print"twoeyes"

defbreast(self,n):

print"Thebreastis:",n

classGirl(object):#Python3:classGril:

age=28

defcolor(self):

print"Thegirliswhite"

classHotGirl(Person,Girl):#多重继承

pass

if__name__=="__main__":

kong=HotGirl()

kong.eye()

kong.breast(90)

kong.color()

printkong.age



twoeyes

Thebreastis:90

Thegirliswhite

28

多重继承的顺序-广度优先

classK1(object):#Python3:classK1:

deffoo(self):

print"K1-foo"#Python3:print("K1-foo"),下同,从略

classK2(object):#Python3:classK2:

deffoo(self):

print"K2-foo"

defbar(self):

print"K2-bar"

classJ1(K1,K2):

pass

classJ2(K1,K2):

defbar(self):

print"J2-bar"

classC(J1,J2):

pass



if__name__=="__main__":

printC.__mro__

m=C()

m.foo()

m.bar()



K1-foo

J2-bar

代码中的printC.__mro__是要打印出类的继承顺序。从上面清晰看出来了。如果要执行foo()方法,首先看J1,没有,看J2,还没有,看J1里面的K1,有了,即C==>J1==>J2==>K1;bar()也是按照这个顺序,在J2中就找到了一个。

这种对继承属性和方法搜索的顺序称之为“广度优先”。

Python2的新式类,以及Python3中都是按照此顺序原则搜寻属性和方法的。

方法

绑定方法

#!/usr/bin/envpython

#coding=utf-8

classPerson(object):#Python3:classPerson:

defeye(self):

print"twoeyes"

defbreast(self,n):

print"Thebreastis:",n

classGirl(object):#Python3:classGril:

age=28

defcolor(self):

print"Thegirliswhite"

classHotGirl(Person,Girl):#多重继承

pass

if__name__=="__main__":

kong=HotGirl()#实例化实现了方法和实例的绑

kong.eye()#调用绑定方法

非绑定方法

在子类中,父类的方法就是非绑定方法,因为在子类中,没有建立父类的实例,却要是用父类的方法。

静态方法和类方法

#!/usr/bin/envpython

#coding=utf-8

__metaclass__=type

classStaticMethod:#静态方法

@staticmethod

deffoo():

print"Thisisstaticmethodfoo()."

classClassMethod:#类方法

@classmethod

defbar(cls):#类方法必须有cls参数

print"Thisisclassmethodbar()."

print"bar()ispartofclass:",cls.__name__

if__name__=="__main__":

static_foo=StaticMethod()#实例化

static_foo.foo()#实例调用静态方法

StaticMethod.foo()#通过类来调用静态方法

print""

class_bar=ClassMethod()

class_bar.bar()

ClassMethod.bar()



Thisisstaticmethodfoo().

Thisisstaticmethodfoo().



Thisisclassmethodbar().

bar()ispartofclass:ClassMethod

Thisisclassmethodbar().

bar()ispartofclass:ClassMethod

在python中:

@staticmethod表示下面的方法是静态方法

@classmethod表示下面的方法是类方法

多态和封装

多态

classCat:

defspeak(self):

print"meow!"

classDog:

defspeak(self):

print"woof!"

classBob:

defbow(self):

print"thankyou,thankyou!"

defspeak(self):

print"hello,welcometotheneighborhood!"

defdrive(self):

print"beep,beep!"

defcommand(pet):

pet.speak()

pets=[Cat(),Dog(),Bob()]

forpetinpets:

command(pet)

Python中的多态特点,Python不检查传入对象的类型,这种方式被称之为“隐式类型”(latentyping)或者“结构式类型”(structuraltyping),也被通俗的称为“鸭子类型”(ducktypeing),Python是弱类型语言。

Java会检查传入对象的类型,所以是强类型语言。

封装和私有化

要了解封装,离不开“私有化”,就是将类或者函数中的某些属性限制在某个区域之内,外部无法调用。

Python中私有化的方法也比较简单,就是在准备私有化的属性(包括方法、数据)名字前面加双下划线。例如:

#!/usr/bin/envpython

#coding=utf-8

classProtectMe(object):#Python3:classProtectMe:

def__init__(self):

self.me="qiwsir"

self.__name="kivi"#私有变量

def__python(self):#私有方法

print"IlovePython."

defcode(self):

print"Whichlanguagedoyoulike?"

self.__python()

if__name__=="__main__":

p=ProtectMe()

printp.me

printp.code()

如何将一个方法变成属性调用?

可以使用property函数。

#!/usr/bin/envpython

#coding=utf-8

classProtectMe(object):#Python3:classProtectMe:

def__init__(self):

self.me="qiwsir"

self.__name="kivi"#私有变量

def__python(self):#私有方法

print"IlovePython."

@property

defcode(self):

print"Whichlanguagedoyoulike?"

self.__python

if__name__=="__main__":

p=ProtectMe()

printp.me

printp.code#调用方法名即可

献花(0)
+1
(本文系换换爱66首藏)