• Python进阶


    2015.8.5

    慕课网Python进阶学习:
     
    函数式编程(functional):
      1.python不是纯函数式编程:允许存在变量
      2.支持高阶函数:函数可作为变量传入
      3.支持闭包:有了闭包就能返回函数
      4.有限度的支持匿名函数
     
    高阶函数:能接收函数作为参数的函数。
    1. def add(x,y,f):
    2. return f(x)+f(y)
    3. print add(4,5,abs)
     其中abs是个求值函数
     
    map()函数:它接收一个函数f和一个list,通过函数f依次作用在list的每个元素上
    1. def format_name(s):
    2. a=s[:1].upper()+s[1:].lower()
    3. return a
    4. print map(format_name,['adam','LISA','barT'])
    reduce()函数:它接收一个函数f和一个list,它传入的函数f必须接收两个参数,对list反复调用f并返回最总结果值。也可接收第三个参数为它的初始值。
    1. def prod(x, y):
    2. return x*y
    3. print reduce(prod,[2,4,5,7,12])
    4. print reduce(prod,[2,4,5,7,12],100)
    第一个输出的运算形式:prod(2,4)=8 ;=>prod(8,5)=40;=>.......依次相乘
    第二个输出的运算形式:prod(100,2)=200 ;=>prod(200,4)=800;=>.......依次相乘
     
    filter()函数:它接收一个函数f和一个list,f对每个元素进行判断,返回true或false,filter()通过判断结果自动过滤不符合条件的元素,返回由符合条件元素组成的新的list
    1. import math
    2. def is_sqr(x):
    3. r=int(math.sqrt(x))
    4. return r*r==x
    5. print filter(is_sqr, range(1,100))
    math.sqrt(x)求x的平方根,返回结果是浮点数,int()将其转为int类型
     
    sorted()自定义排序函数:接收一个比较函数f和一个list,f接收两个待比较的元素x,y,如果x应该排在y的前面,返回-1,如果x应该排在y的后面返回1,如果x,y相等,返回0
    1. def cmp_ignore_case(s1, s2):
    2. u1=s1.upper()
    3. u2=s2.upper()
    4. if u1<u2:
    5. return-1
    6. if u1==u2:
    7. return0
    8. if u1>u2:
    9. return1
    10. print sorted(['bob','about','Zoo','Credit'],cmp_ignore_case)
    从小到大排列,忽略大小写
     
    返回函数:
    1. def calc_prod(lst):
    2. def g():
    3. def d(x,y):
    4. return x * y
    5. return reduce(d,lst,1)
    6. return g
    7. f = calc_prod([1,2,3,4])
    8. print f()
    闭包:内层函数应用了外层函数的变量,然后返回内层函数的情况称为闭包。注意:返回函数不要引用任何循环变量或者后续会发生编发的变量
    1. def count():
    2. fs =[]
    3. for i in range(1,4):
    4. def f(x):
    5. def g():
    6. return x*x;
    7. return g
    8. r=f(i)
    9. fs.append(r)
    10. return fs
    11. f1, f2, f3 = count()
    12. print f1(), f2(), f3()
    匿名函数:lambda      只能有一个表达式,不写return,返回值就是该表达式的结果
    1. print filter(lambda s:s and len(s.strip())>0,['test',None,'','str',' ','END'])
    s为匿名函数参数
     
     
    2015.8.6
    装饰器(decorator):
    极大的简化代码,避免每个函数编写重复性代码
    使用@在调用装饰器函数的函数之前
    不带参数装饰器
    打印日志:@log
    def log(f):
    def fn(x):
    print'call '+ f.__name__ +'()...'
    return f(x)
    return fn
     
    @log
    def factorial(n):
    return reduce(lambda x,y: x*y, range(1, n+1))
    print factorial(10)
    #此处代码如下
    factorial=log(
    对于参数不是一个的,调用将报错,@log写死了只含有一个参数的返回值,要让@log自适应任何参数的函数可以使用*args和**kw,保证任意个参数都能正常调用
    def log(f):
    def fn(*args,**kw):
    print'call '+ f.__name__ +'()...'
    return f(*args,**kw)
    return fn
    @log
    def factorial(n):
    return reduce(lambda x,y: x*y, range(1, n+1))
    print factorial(10)
    检测性能:@performance
    import time
     
    def performance(f):
    def fn(*args,**kw):
    t1=time.time()
    r=f(*args,**kw)
    t2=time.time()
    print'call %s() in %fs'%(f.__name__,(t2-t1))
    return r
    return fn
    @performance
    def factorial(n):
    return reduce(lambda x,y: x*y, range(1, n+1))
     
    print factorial(10)
    数据库事务:@transaction
    URL路由:@post('/register')
     
    带参数的装饰器
    def log(str):
    def log_decorator(f):
    def fn(*args,**kw):
    print'call [%s] %s()...'%(str,f.__name__)
    return f(*args,**kw)
    return fn
    return log_decorator
     
    @log('debug')
    def factorial(n):
    return reduce(lambda x,y: x*y, range(1, n+1))
    #factorial=log(factorial)
    print factorial(10)
    import time
     
    def performance(unit):
    def pp(f):
    def ff(*a,**k):
    t1=time.time()
    r=f(*a,**k)
    t2=time.time()
    print'call %s() in %f%s'%(f.__name__,t2-t1,unit)
    return r
    return ff
    return pp
     
    @performance('ms')
    def factorial(n):
    return reduce(lambda x,y: x*y, range(1, n+1))
     
    print factorial(10)
    由于decorator会改造函数,便会改变函数的__name__,__doc__等其他属性,所以就需要将原函数属性复制到新函数中使用functools自动化完成这个复制任务
    import functools
    def log(f):
    #@functools.wraps(f)
    def wrapper(*args,**kw):
    print'call...'
    return f(*args,**kw)
    return wrapper
    @log
    def ff():
    return1
    print ff.__name__
    此时输出wrapper    若加上@functools.wraps(f) 输出ff
    import time, functools
     
    def performance(unit):
    def pp(f):
    @functools.wraps(f)
    def ff(*rags,**k):
    t1=time.time()
    r=f(*rags,**k)
    t2=time.time()
    print'call %s in %f%s'%(f.__name__,t2-t1,unit)
    return r
    return ff
    return pp
     
    @performance('ms')
    def factorial(n):
    return reduce(lambda x,y: x*y, range(1, n+1))
    print factorial(10)
    print factorial.__name__
    偏函数:
    functools.partial可以将一个参数多的函数变为一个参数少的函数,少的函数需要在创建是指定默认值
    import functools
     
    sorted_ignore_case = functools.partial(sorted,cmp=lambda s1,s2:cmp(s1.upper(),s2.upper()))
     
    print sorted_ignore_case(['bob','about','Zoo','Credit'])
    cmp(x,y)函数为对比函数 x>y返回1 x=y返回0 x<y 返回-1
     
    模块和包:
    包便是文件夹,.py文件便是模块,包中必须要有__init__.py文件,包的每层目录中都需要有
    用import引用其他模块的函数等
    将同名模块放入不同的包中
    #test.py
    import p1.unit
    print p1.unit.f(2,1)
    os.path模块提供了is.dir()和isfile()函数,判断指定目录和文件是否存在
    import os.path
     
    print os.path.isdir(r'/data/webroot/resource/python')
    print os.path.isfile(r'/data/webroot/resource/python/test.txt')
    动态导入模块(动态引入需要在直接引入之前):
    同样实现stringIO的功能,但是CStringIO模块部分是用c写的,所以CStringIO要比StringIO运行要快。
    try:
    from cStringIO importStringIO
    exceptImportError:
    fromStringIOimportStringIO
    try:
    import json
    exceptImportError:
    import simplejson as json
     
    print json.dumps({'python':2.7})
    使用import...as...动态导入不同名称的模块
     
    使用__future__
    python新版本会引入新的功能,但是,实际上这些功能再上一个老版本中已经存在,要试用某些新特性,就可以通过导入__future__模块的某些功能来实现。
    from __future__ import division#若不引入,print 10/3输出3,引入输出3.3333333
    import p1.hello
     
    print10/3
    print p1.hello.factorial(10)
    from __future__ import unicode_literals
     
    s = b'am I an unicode?'
    print isinstance(s, unicode)
    在现在的版本中,字符串同意为unicode不需要加u前缀,而str 必须加b前缀
     
    安装第三方模块
    工具:easy_install   pip(官方推荐,内置到python2.7.9)
    确保python版本为python2.7.9以上版本,在命令提示符下使用pip install web.py(web.py为第三方模块)
     
    面向对象编程
    classPerson(object):
    pass
    类名首字母大写,object为该类继承的类
    classPerson(object):
    def __init__(self,name):#构造函数
    self.name=name
     
    xiaoming =Person('xiaoming')
    xiaohong =Person('xiaohong')
     
    print xiaoming.name
    print xiaohong.name
    print xiaoming.name==xiaohong.name
    classPerson(object):
    pass
     
    p1 =Person()
    p1.name ='Bart'
     
    p2 =Person()
    p2.name ='Adam'
     
    p3 =Person()
    p3.name ='Lisa'
     
    L1 =[p1, p2, p3]
    L2 = sorted(L1,lambda p1,p2:cmp(p1.name,p2.name))
     
    print L2[0].name
    print L2[1].name
    print L2[2].name
    python关键字参数和可变参数
    python关键字参数用**kw表示,在调用时可以默认赋值且可以为任意个的参数
    可变参数用*args表示,在调用时可以是任意个的参数
    def foo1(arg1,arg2,*arg,**keywords):
    print"arg1 parameters is ",arg1
    print"arg2 parameters is ",arg2
    print"Arbitrary parameter is ", arg
    print"keywords parameter is ",keywords
     
    foo1(1,2,3,4,5,6,k1=1,k2=2,k3=3)
    构造函数初始化,参数是可以为关键字参数或可变参数
    classPerson(object):
    def __init__(self,name,sex,bor,*args,**kw):
    self.name=name
    self.sex=sex
    self.bor=bor
    for k,v in kw.iteritems():
    setattr(self,k,v)
    for c in args:
    setattr(self,c)
     
    xiaoming =Person('Xiao Ming','Male','1990-1-1', job='Student',job2='sty')
     
    print xiaoming.name
    print xiaoming.job
    print xiaoming.job2
    访问限制:
    设置某属性为外部无法访问用双下划线开头 __
    classPerson(object):
    def __init__(self, name, score):
    self.name=name
    self.__score=score
     
    p =Person('Bob',59)
     
    print p.name
    print p.__score
    创建类属性(不同于实例属性)
    classPerson(object):
    count=0
    def __init__(self,name):
    Person.count=Person.count+1
    self.name=name
     
    p1 =Person('Bob')
    printPerson.count
     
    p2 =Person('Alice')
    printPerson.count
     
    p3 =Person('Tim')
    printPerson.count
    当实例属性和类属性重名时,实例属性优先级高,实例中是不能修改类属性的
    classPerson(object):
     
    __count =0
    count=0
     
    def __init__(self, name):
    Person.__count=Person.__count+1
    self.name=name
     
    p1 =Person('Bob')
    p2 =Person('Alice')
     
    printPerson.__count
    printPerson.count
    定义实例函数
    #-*- coding:utf-8 -*-
    classPerson(object):
     
    def __init__(self, name, score):
    self.__score=score
    self.name=name
     
    def get_grade(self):
    if self.__score>=80:
    return'优秀'
    if self.__score>=60:
    return'及格'
    if self.__score<60:
    return'不及格'
     
    p1 =Person('Bob',90)
    p2 =Person('Alice',65)
    p3 =Person('Tim',48)
     
    print p1.get_grade()
    print p2.get_grade()
    print p3.get_grade()
    最上面那句是为了使其支持中文编码
     
    方法也可以看出是属性,可以将方法动态的添加到实例上,只是需要使用types.MethodType()将一个函数变为一个方法
    import types
    def fn_get_grade(self):
    if self.score >=80:
    return'A'
    if self.score >=60:
    return'B'
    return'C'
     
    classPerson(object):
    def __init__(self, name, score):
    self.name = name
    self.score = score
     
    p1 =Person('Bob',90)
    p1.get_grade = types.MethodType(fn_get_grade, p1,Person)
    print p1.get_grade()
    # => A
    p2 =Person('Alice',65)
    print p2.get_grade()
    # ERROR: AttributeError: 'Person' object has no attribute 'get_grade'
    # 因为p2实例并没有绑定get_grade
     
    classPerson(object):
     
    def __init__(self, name, score):
    self.name = name
    self.score = score
    self.get_grade =lambda:'A'
     
    p1 =Person('Bob',90)
    print p1.get_grade
    print p1.get_grade()
    定义类方法,和属性相似,方法也分实例方法和类方法
    classPerson(object):
    count=0
    @classmethod
    def howMany(cls):
    return cls.count
    def __init__(self,name):
    self.name=name
    Person.count=Person.count+1
    printPerson.howMany()
    p1=Person('xiaoming')
    printPerson.howMany()
    classPerson(object):
     
    __count =0
     
    def __init__(self,name):
    Person.__count=Person.__count+1
    self.name=name
    @classmethod
    def how_many(cls):
    return cls.__count
     
    printPerson.how_many()
     
    p1 =Person('Bob')
     
    printPerson.how_many()
    继承
    classPerson(object):
    count=0
    @classmethod
    def howMany(cls):
    return cls.count
    def __init__(self,name,gender):
    self.name=name
    Person.count=Person.count+1
     
    classStudent(Person):
    def __init__(self,name,gender,school,score):
    super(Student,self).__init__(name,gender)
    self.school=school
    self.score=score
    printPerson.howMany()
    p1=Person('xiaoming','m')
    s1=Student('n','s','d',11)
     
    print s1.name
     
    printPerson.howMany()
    isinstance(s,type)函数,检测s是否是type类型,可用于判断属性是否是int、str等类型
    classPerson(object):
     
    def __init__(self, name, gender):
    self.name = name
    self.gender = gender
     
    classStudent(Person):
     
    def __init__(self, name, gender, score):
    super(Student, self).__init__(name, gender)
    self.score = score
     
    classTeacher(Person):
     
    def __init__(self, name, gender, course):
    super(Teacher, self).__init__(name, gender)
    self.course = course
     
    t =Teacher('Alice','Female','English')
     
    print isinstance(t,Person)
    print isinstance(t,Student)
    print isinstance(t,Teacher)
    print isinstance(t,object)
    多态
    classPerson(object):
    def __init__(self, name, gender):
    self.name = name
    self.gender = gender
    def whoAmI(self):
    return'I am a Person, my name is %s'% self.name
     
    classStudent(Person):
    def __init__(self, name, gender, score):
    super(Student, self).__init__(name, gender)
    self.score = score
    def whoAmI(self):
    return'I am a Student, my name is %s'% self.name
     
    classTeacher(Person):
    def __init__(self, name, gender, course):
    super(Teacher, self).__init__(name, gender)
    self.course = course
    def whoAmI(self):
    return'I am a Teacher, my name is %s'% self.name
     
    def who_am_i(x):
    print x.whoAmI()
     
    p =Person('Tim','Male')
    s =Student('Bob','Male',88)
    t =Teacher('Alice','Female','English')
     
    who_am_i(p)
    who_am_i(s)
    who_am_i(t)
    其中调用whoAmI函数时,先找该对象的方法,没有再向其父类找
     
    python提供了open()方法来打开一个磁盘文件,并返回File对象,File对象有一个read()方法可以读取文件内容
    任何含有read()方法的函数都可以称为 File-like-object 都可以直接将其对象传给json.load()
    import json
    classStudents(object):
    def read(self):
    return r'["Tim", "Bob", "Alice"]'
    s =Students()
    print json.load(s)
    多重继承  从多个父类继承,称为多重继承
    在多重继承中,父类的父类的__init__方法只会被调用一次
    Python的网络服务器有TCPServer、UDPServer、UnixStreamServer、UnixDatagramServer
    服务器运行模式有多进程ForkingMixin和多线程ThreadingMixin
    classPerson(object):
    pass
     
    classStudent(Person):
    pass
     
    classTeacher(Person):
    pass
     
    classSkillMixin(object):
    pass
     
    classBasketballMixin(SkillMixin):
    def skill(self):
    return'basketball'
     
    classFootballMixin(SkillMixin):
    def skill(self):
    return'football'
     
    classBStudent(BasketballMixin,Student):
    pass
     
    classFTeacher(FootballMixin,Teacher):
    pass
     
    s =BStudent()
    print s.skill()
     
    t =FTeacher()
    print t.skill()
    获取对象信息
     
    type(x)获取对象x的类型 dir(x)获取对象x的所有属性信息。
    若知道一个属性名称,要获取或设置对象的属性,就需要用到getattr()和serattr()
    1. #-*- coding:utf-8 -*-
    2. classPerson(object):
    3. def __init__(self, name, gender):
    4. self.name = name
    5. self.gender = gender
    6. classStudent(Person):
    7. def __init__(self, name, gender, score):
    8. super(Student, self).__init__(name, gender)
    9. self.score = score
    10. def whoAmI(self):
    11. return'I am a Student, my name is %s'% self.name
    12. s =Student('Bob','Male',88)
    13. print type(s)
    14. print getattr(s,'name')
    15. print getattr(s,'age',20)#不存在age值则返回默认值20
    16. setattr(s,'name','Adam')
    17. print dir(s)
     
     
    2015.8.7
    特殊方法(魔术方法)
    特殊方法定义的class中,不需要直接调用,Python的某些函数或操作符会调用对应的特殊方法
    #-*- coding:utf-8 -*-
    classPerson(object):
    def __init__(self, name, gender):
    self.name = name
    self.gender = gender
     
    s =Person('Bob','Male')
    print s
    print s.__str__()#输出结果同上__str__()便是一个特殊方法,用于显示给用户
    print s.__rpr__()#用于显示给开发人员
    特殊方法也可以重写
    classPerson(object):
     
    def __init__(self, name, gender):
    self.name = name
    self.gender = gender
     
    classStudent(Person):
     
    def __init__(self, name, gender, score):
    super(Student, self).__init__(name, gender)
    self.score = score
     
    def __str__(self):
    return'Student: %s,%s,%s'%(self.name,self.gender,self.score)
    __repr__=__str__
    s =Student('Bob','male',88)
    print s
    __cmp__()方法
    对于int,str等内置数据类型排序是,python的sorted()安装默认额比较函数cmp排序,但是对一组Student类的实例排序是就必须提供我们自己的特殊方法__cmp__()
    classStudent(object):
     
    def __init__(self, name, score):
    self.name = name
    self.score = score
     
    def __str__(self):
    return'(%s: %s)'%(self.name, self.score)
     
    __repr__ = __str__
     
    def __cmp__(self, s):
    if self.score<s.score:
    return-1
    elif self.score==s.score:
    return0
    else:
    return1
     
    L =[Student('Tim',99),Student('Bob',88),Student('Alice',99)]
    print sorted(L)
    __len__()方法
    如果类的实例想要使用len()方法必须实现__len__()方法
    classFib(object):
     
    def __init__(self, num):
    a,b,L=0,1,[]
    for n in range(num):
    L.append(a)
    a,b=b,a+b
    self.numbers=L
     
    def __str__(self):
    return str(self.numbers)
    __repr__=__str__
     
    def __len__(self):
    return len(self.numbers)
     
    f =Fib(10)
    print f
    print len(f)
    数学运算
    有理数:有理数是一个整数a和一个非零整数b的比,例如3/8
    def gcd(a,b):#处理有理数归约
    if b==0:
    return a
    return gcd(b,a%b)
    classRational(object):
    def __init__(self, p, q):
    self.p = p
    self.q = q
     
    def __add__(self, r):
    returnRational(self.p * r.q + self.q * r.p, self.q * r.q)
     
    def __sub__(self, r):
    returnRational(self.p*r.q-self.q*r.p,self.q*r.q)
     
    def __mul__(self, r):
    returnRational(self.p*r.p,self.q*r.q)
     
    def __div__(self, r):
    returnRational(self.p*r.q,self.q*r.p)
     
    def __str__(self):
    g=gcd(self.p,self.q)
    return'%s/%s'%(self.p/g,self.q/g)##########
     
    __repr__ = __str__
     
    r1 =Rational(1,2)
    r2 =Rational(1,4)
    print r1 + r2
    print r1 - r2
    print r1 * r2
    print r1 / r2
    类型转换
    classRational(object):
    def __init__(self, p, q):
    self.p = p
    self.q = q
     
    def __int__(self):
    return self.p // self.q
     
    def __float__(self):
    return float(self.p)/self.q
     
    print float(Rational(7,2))
    print float(Rational(1,3))
    @property装饰器
    classStudent(object):
     
    def __init__(self, name, score):
    self.name = name
    self.__score = score
     
    @property #如get方法
    def score(self):
    return self.__score
     
    @score.setter #如set方法
    def score(self, score):
    if score <0or score >100:
    raiseValueError('invalid score')
    self.__score = score
     
    @property
    def grade(self):
    if self.score<60:
    return'C'
    if self.score<80:
    return'B'
    return'A'
     
    s =Student('Bob',59)
    print s.grade
     
    s.score =60
    print s.grade
     
    s.score =99
    print s.grade
    __slots__方法控制类属性如下
    classStudent(object):
    __slots__ =('name','gender','score')
    def __init__(self, name, gender, score):
    self.name = name
    self.gender = gender
    self.score = score
    s =Student('Bob','male',59)
    s.name ='Tim'# OK
    s.score =99# OK
    s.grade ='A'
    在__slots__中只定义了三个属性,所以会导致s.grade不能正常运行,只有在__slots__中定义了的属性才能够运行
    classPerson(object):
     
    __slots__ =('name','gender')
     
    def __init__(self, name, gender):
    self.name = name
    self.gender = gender
     
    classStudent(Person):
     
    __slots__ =('score',)#当只有一个属性是,之后需要加个,
     
    def __init__(self,name,gender,score):
    super(Student,self).__init__(name,gender)
    self.name=name
    self.gender=gender
    self.score=score
     
    s =Student('Bob','male',59)
    s.name ='Tim'
    s.score =99
    print s.score
    __call__   将一个实例编程一个可调用对象,即时将一个实例变为一个可调用函数
    classPerson(object):
    def __init__(self, name, gender):
    self.name = name
    self.gender = gender
     
    def __call__(self, friend):
    print'My name is %s...'% self.name
    print'My friend is %s...'% friend
    p=Person('bob','man')
    p('tim')
    classFib(object):
    def __call__(self,num):
    a,b,L=0,1,[]
    for n in range(num):
    L.append(a)
    a,b=b,a+b
    return L
     
    f =Fib()
    print f(10)
     



  • 相关阅读:
    Flask 的 请求扩展 与 中间件
    Flask的配置文件 与 session
    django中的FBV和CBV
    Flask开启多线程、多进程
    WPF获取原始控件样式
    一个40岁老码农的总结,奋斗没有意义,选择大于努力
    FastText 分析与实践
    Flask的多app应用,多线程如何体现
    Python 远程调用MetaSploit
    GitLab 7.5.3 CentOS7安装和SMTP配置
  • 原文地址:https://www.cnblogs.com/kinmos/p/6829851.html
Copyright © 2020-2023  润新知