偏函数
Python 的functools模块提供了很多有用的功能,其中一个就是偏函数。这个偏函数和数学意义上的偏函数不一样
import functools
print(int('123')) #默认是按照10进制进行转换
print(int('123',base=16)) #按照16进制进行转换
def int_2(num,base=2):
return int(num,base)
print(int_2('1001'))
int_2=functools.partial(int,base=2) #偏函数
print(int_2('100000'))
偏函数的作用就是把一个函数给固定住(也就是设置默认值),返回一个新函数,调用这个新函数会更简单
面向对象进阶
动态语言:可以在运行的过程中,修改代码
静态语言:编译时已经确定好代码,运行过程中不能修改
‘slots’
#限制类动态增加属性
class Student(object):
#只允许当前Student拥有name和sex属性
__slots__ = ('name','sex','age')
#验证slots
s=Student()
s.name='李四'
s.sex='女'
s.age=23
print(s)
class Person(object):
#age属性的值限制的范围是0-88
def get_age(self):
return self._age
def set_age(self,value):
if value>=0 and value<=88:
self._age=value
else:
print('age的值必须在0-88之间')
self._age=0#0为age的初始值
#raise ValueError('age的值必须在0-88之间')
if __name__ == '__main__':
p=Person()
#p.age=18
p.set_age(100)
print(p.get_age())
@property
把一个属性直接暴露出去
多重继承
class Father(object):
def work(self):
print('父亲在工作')
class Mather(object):
def work(self):
print('母亲在工作')
class Child(Father,Mather): #多继承
def __init__(self,xname):
self.name=xname
if __name__ == '__main__':
c=Child('张三')
c.work() #如果多个父类中都有同样的函数,按照优先级来调用
print(Child.__mro__)
定制类
形如__xxx__的变量或者函数名就要注意,这是在Python中有特殊用途的
class Person(object):
def __init__(self,xname):
self.name=xname
#斐波那契数列
self.a,self.b=0,1
#用于定制对象的描述信息
def __str__(self):
return "Person object(name:%s)"%self.name
#person默认不是可迭代对象,变成一个可迭代对象,必须返回一个迭代器
def __iter__(self): #生成一个斐波那契数列
return self
#person变成一个迭代器
def __next__(self):
self.a,self.b=self.b,self.a+self.b #计算下一个值
if self.a>1000: #如果出现一个大于1000的数字,退出循环
raise StopIteration
return self.a
if __name__ == '__main__':
p=Person('张三')
print(p)
for n in p:
print(n)
call
对象和函数不是那么清晰的
gatter
处理函数不存在或者报错的情况下
枚举类
#当项目中需要使用12个月份时
#
# Jan=1
# Feb=2
# ...
from enum import Enum
Month=Enum('抬头-month',('jan','feb','mar','apr','may','jun','jul'))
#把整个枚举中的所有值遍历出来
print(Month.__members__) #枚举中的值自动从1开始,不会重复
#得到二月份的值
print(Month['feb'].value)
#根据值来得到月份的名字
print(Month(2).name)
#定义一个颜色的常量枚举
class Color(Enum): #第二种:自定义一个枚举类
red=100
green=200
blue=300
yellow=200 #不允许key相同或者value,如果value相同根据value取name只能取到第一个
print(Color(200))
元类
class Person(object):
def say(self,words='hello'):
print("我说:%s"%words)
#引人模块,需要模块的路径
from Python高级.元类 import Person
#from引入模块后,则动态的创建一个Person类
p=Person() #创建一个Person类的实例
p.say('hello')
print(type(p)) #把实例p的类型打印出来
print(type(Person)) #Person类的类型打印
#type()函数,使用用于创建类的函数
type(name,bases,dict)
name----类的名称
bases----基类的元组
dict—字典、类内定义的命名空间变量
#引人模块,需要模块的路径
from Python高级.元类 import Person
#from引入模块后,则动态的创建一个Person类
def func(self, words='hello'):
print("我说:%s" % words)
#使用type()创建一个Person类
Person=type('Person',(object,),dict(say=func))
p=Person() #创建一个Person类的实例
p.say('hello')
print(type(p)) #把实例p的类型打印出来
print(type(Person)) #Person类的类型打印,本质就是打印Person类的元类
#type()函数,使用用于创建类的函数
元类就是创建类这种对象的东西
def upper_attr(class_name,class_parent,class_attrs):
#变量任意一个类所有的属性,把非私有的属性名字改成大写的
#定义一个字典保存改完名字之后的属性集合
new_attrs={}
for name,value in class_attrs.items():
if not name.startswith('_'): #判断是否为:非私有的属性
new_attrs[name.upper()]=value
#直接调用type来创建一个类
return type(class_name,class_parent,new_attrs)
#测试
class Emp(object,metaclass=upper_attr):
name='站上'
acl=5000
if __name__ == '__main__':
print(hasattr(Emp,'name')) #判断Emp类中是否有名字为name
print(hasattr(Emp,'NAME')) #判断Emp类中是否有名字为NAME
print(hasattr(Emp,'ACL')) #判断Emp类中是否有名字为ACL
正则表达式的编译
正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串
import re
tel_l='''aesdf 13811011234 aa1a3hi233rhi3 87156340 affa124564531346546 afa19454132135'''
tel_2='13812345678abc'
pattern=re.compile(r'1[3,9]\d{9}') #编译正则表达式之后得到一个编译对象
result=pattern.search(tel_l) #search只会返回第一个匹配的结果,如果没有匹配成功则返回none
print(result)
print(result.group(0)) #返回第一个匹配结果
print(result.span(0)) #返回第一个匹配结果的下标
result2=pattern.match(tel_2) #match函数是从第一个字符开始匹配,如果第一个字符不匹配,则返回none
print(result2.group(0))
正则表达式的写法
import re
tel_l='''aesdf 13811011234 aa1a3hi233rhi3 87156340 affa124564531346546 afa19454132135'''
tel_2='13812345678abc'
pattern=re.compile(r'1[3,9]\d{9}') #编译正则表达式之后得到一个编译对象
result=pattern.search(tel_l) #search只会返回第一个匹配的结果,如果没有匹配成功则返回none
print(result)
print(result.group(0)) #返回第一个匹配结果
print(result.span(0)) #返回第一个匹配结果的下标
print(result.pos,result.endpos)
import re
one ='a'
print(re.match('.',one).group()) #.可以匹配任意单个字符
two='2'
two_2='Hello Python'
print(re.match('[1,2,3]',two).group())
print(re.match('[hH]',two_2).group()) #匹配大小或者小写的H
three='天空1号,发射成功'
print(re.match('天空\d',three).group())
print(re.search('\d',three).group())
转义字符
import re
#需求1:匹配一个字符串第一个字母是大写,后面的字母必须是小写或者没有
print(re.match('[A-Z][a-z]*','Mm').group())
print(re.match('[A-Z][a-z]*','M').group())
print(re.match('[A-Z][a-z]*','Mmsdsfsfsd').group())
#需求2:匹配一个变量名
print(re.match(r'[a-zA-Z]+[\w]*','name1'))
print(re.match(r'[a-zA-Z_]+[\w]*','_name1'))
print(re.match('[a-zA-Z]+[\w]*','2name1'))
#需求3:匹配从0到99之间的任意一个数字
print(re.match('[0-9]?[0-9]','22'))
#需求4:匹配密码(8-20位,可以是大小写的字母,数字,下划线)
print(re.match('[a-zA-Z0-9_]{8,20}','2323243dfs').group())
#练习5:匹配163的邮箱地址,用户名包含6——18个字符,可以是字母、数字、下划线,但是必须以字母开头
emails='''
awhahlf@163.com affafafafaaaaaaaaaaaaaaaa@163.com afa_@163.com 225afafaf@163.com aaaa____@qq.com aaaa____@163.com
'''
print(re.search('[a-zA-Z][\w]{5,17}@163\.com',emails).group())
匹配边界
import re
emails='''
awhahlf@163.com
affafafafaaaaaaaaaaaaaaaa@163.com
afa_@163.com
225afafaf@163.com
aaaa____@qq.com
aaaa____@163.com
'''
print(re.search('^[a-zA-Z][\w]{5,17}@163\.com',emails,re.MULTILINE).group())
#取反 [^ ]表示取反
#^[ ]以……开头
print(re.search('[^0-9]','9'))
匹配分组
import re
#需求1,匹配从0-100的数字,包括100
print(re.match('[1-9]?\d','98').group())
print(re.match('[1-9]?\d$','78').group())
print(re.match('[1-9]?\d$|100','100').group())
#需求2:匹配网易邮箱,163.com也可以是126.com
emails='''
awhahlf@163.com
affafafafaaaaaaaaaaaaaaaa@163.com
afa_@163.com
225afafaf@163.com
aaaawe__@126.com
aaaa____@163.com
'''
print(re.search('^[a-zA-Z][\w]{5,17}@(163|126)\.com$',emails,re.MULTILINE).group())
#需求3:匹配<h1>hello</h1>
print(re.match('<[a-zA-Z]+>\w*</[a-zA-Z]+>','<p>hello</p>'))
print(re.match('<[a-zA-Z]+>\w*</[a-zA-Z]+>','<div>hello</div>'))
print(re.match('<[a-zA-Z]+>\w*</[a-zA-Z]+>','<p>hello</div>'))
print(re.match(r'<([a-zA-Z]+)>\w*</\1>','<p>hello</p>'))
#第二种写法,匹配一个网页的嵌套标签
line='<div><p>hello</p></div>'
print(re.match(r'<(?P<n1>\w*)><(?P<n2>\w*)>.*</(?P=n2)></(?P=n1)>',line).group())