为了账号安全,请及时绑定邮箱和手机立即绑定

python进阶

廖雪峰 移动开发工程师
难度中级
时长 3小时33分
学习人数
综合评分9.20
575人评价 查看评价
9.6 内容实用
9.0 简洁易懂
9.0 逻辑清晰
  • 内层函数引用了外层函数的变量(参数也算变量),然后返回内层函数的情况,称为闭包(Closure)

    闭包的特点是返回的函数还引用了外层函数的局部变量,所以,要正确使用闭包,就要确保引用的局部变量在函数返回后不能变

  • class Fib(object):


        def __init__(self, num):

            l = []

            a,b = 0,1

            for i 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)


  • class Person(object):


        def __init__(self, name, gender, **kw):

            self.name = name

            self.gender = gender

            for k,v in kw.items():

                setattr(self,k,v)


    p = Person('Bob', 'Male', age=18, course='Python')

    print p.age

    print p.course


  • class Person(object):

        

        count = 0

        

        def __init__(self,name):

            self.name = name

            Person.count += 1


    p1 = Person('Bob')

    print Person.count


    p2 = Person('Alice')

    print Person.count


    p3 = Person('Tim')

    print Person.count


  • class Person(object):
        def __init__(self,name,gender,birth,**kwargs):
            self.name = name
            self.gender = gender
            self.birth = birth
            for k,v in kwargs.items():
                setattr(self,k,v)
    
    xiaoming = Person('Xiao Ming', 'Male', '1990-1-1', job='Student')
    
    print(xiaoming.name)
    print(xiaoming.job)


  • class Person(object):    
        pass
        
    p1 = Person()
    p1.name = 'Bart'
    
    p2 = Person()
    p2.name = 'Adam'
    
    p3 = Person()
    p3.name = 'Lisa'
    
    L1 = [p1, p2, p3]
    L2 = sorted(L1,key=lambda x:x.name.upper())
    
    print L2[0].name
    print L2[1].name
    print L2[2].name


  • import functools
    
    sorted_ignore_case = functools.partial(sorted,key=lambda x:x.upper())
    
    print (sorted_ignore_case(['bob', 'about', 'Zoo', 'Credit']))


  • class Student(Person):
        __slots__ = ('score',)
        def __init__(self, name, gender, score):
            super(Student, self).__init__(name, gender)
            self.score = score
    从Person中继承了,并新增加一个score的属性


  • 使用 get/set 方法来封装对一个属性的访问在许多面向对象编程的语言中都很常见。

  • Python的 decorator 本质上就是一个高阶函数,它接收一个函数作为参数,然后,返回一个新函数。

  • 直接把 lambda 函数赋值给 self.get_grade 和绑定方法有所不同,函数调用不需要传入 self,但是方法调用需要传入 self。

  • 要让 @log 自适应任何参数定义的函数,可以利用Python的 *args 和 **kw,保证任意个数的参数总是能正常调用:

    def log(f):
        def fn(*args, **kw):
            print 'call ' + f.__name__ + '()...'
            return f(*args, **kw)
        return fn

    现在,对于任意函数,@log 都能正常工作。


  • 通过对比可以看出,匿名函数 lambda x: x * x 实际上就是:

    def f(x):
        return x * x

    关键字lambda 表示匿名函数,冒号前面的 x 表示函数参数。

    匿名函数有个限制,就是只能有一个表达式,不写return,返回值就是该表达式的结果。


  • strip()  去除字符列表内为空的元素(None,False,'\n'‘‘,等)


  • 如果要提高Python代码的运行速度,最简单的方法是把某些关键函数用 C 语言重写,这样就能大大提高执行速度。

    同样的功能,StringIO 是纯Python代码编写的,而 cStringIO 部分函数是 C 写的,因此 cStringIO 运行速度更快。

    利用ImportError错误,我们经常在Python中动态导入模块:

    try:
        from cStringIO import StringIO
    except ImportError:
        from StringIO import StringIO

    上述代码先尝试从cStringIO导入,如果失败了(比如cStringIO没有被安装),再尝试从StringIO导入。这样,如果cStringIO模块存在,则我们将获得更快的运行速度,如果cStringIO不存在,则顶多代码运行速度会变慢,但不会影响代码的正常执行。

    try 的作用是捕获错误,并在捕获到指定错误时执行 except 语句。


  • python3报错,需要修改下:

    import functools
    
    
    class Student(object):
    
        def __init__(self, name, score):
            self.name = name
            self.score = score
    
        def __str__(self):
            return '(%s: %s)' % (self.name, self.score)
    
        __repr__ = __str__
    
        # 重写魔术方法 __cmp__ 排序规则:按照分数从高到底排序,分数相同的按名字排序。
        # python3 失效
    
    
    def my_cmp(self, s):
        if self.score > s.score:
            return -1
        elif self.score < s.score:
            return 1
        else:
            if self.name < s.name:
                return -1
            elif self.name > s.name:
                return 1
            else:
                return 0
    
    
    L = [Student('Tim', 99), Student('Bob', 88), Student('Alice', 99)]
    print(sorted(L, key=functools.cmp_to_key(my_cmp)))


  • 传入**kw 即可传入任意数量的参数

    eg:
        def __init__(self, name, gender, **kw):        self.name=name        self.gender=gender        for k, v in kw.iteritems():            setattr(self, k, v)


  • 像这种内层函数引用了外层函数的变量(参数也算变量),然后返回内层函数的情况,称为闭包(Closure)。

    闭包的特点是返回的函数还引用了外层函数的局部变量,所以,要正确使用闭包,就要确保引用的局部变量在函数返回后不能变。

  • >>> map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9])
    [1, 4, 9, 16, 25, 36, 49, 64, 81]

    通过对比可以看出,匿名函数 lambda x: x * x 实际上就是:

    def f(x):
        return x * x

    关键字lambda 表示匿名函数,冒号前面的 x 表示函数参数。

  • @log('DEBUG')
    def my_func():
        pass
    把上面的定义翻译成高阶函数的调用,就是:
    my_func = log('DEBUG')(my_func)
    再展开一下:
    log_decorator = log('DEBUG')
    my_func = log_decorator(my_func)
    所以,带参数的log函数首先返回一个decorator函数,再让这个decorator函数接收my_func并返回新函数
  • 任务

    改进一下前面定义的斐波那契数列:

    class Fib(object):
        ???

    请加一个__call__方法,让调用更简单:

    >>> f = Fib()
    >>> print f(10)
    [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
    • ?不会了怎么办

    • 要正确定义参数:__call__(self, num)

      参考代码:

      class Fib(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)


  • 任务

    假设Person类通过__slots__定义了name和gender,请在派生类Student中通过__slots__继续添加score的定义,使Student类可以实现name、gender和score 3个属性。

     

    • ?不会了怎么办

    • Student类的__slots__只需要包含Person类不包含的score属性即可。

      参考代码:

      class Person(object):
          __slots__ = ('name', 'gender')
          def __init__(self, name, gender):
              self.name = name
              self.gender = gender
      
      class Student(Person):
          __slots__ = ('score',)
          def __init__(self, name, gender, score):
              super(Student, self).__init__(name, gender)
              self.score = score
      
      s = Student('Bob', 'male', 59)
      s.name = 'Tim'
      s.score = 99
      print s.score


首页上一页1234567下一页尾页

举报

0/150
提交
取消
课程须知
本课程是Python入门的后续课程 1、掌握Python编程的基础知识 2、掌握Python函数的编写 3、对面向对象编程有所了解更佳
老师告诉你能学到什么?
1、什么是函数式编程 2、Python的函数式编程特点 3、Python的模块 4、Python面向对象编程 5、Python强大的定制类

微信扫码,参与3人拼团

意见反馈 帮助中心 APP下载
官方微信
友情提示:

您好,此课程属于迁移课程,您已购买该课程,无需重复购买,感谢您对慕课网的支持!