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

python进阶

廖雪峰 移动开发工程师
难度中级
时长 3小时33分
学习人数
综合评分9.20
575人评价 查看评价
9.6 内容实用
9.0 简洁易懂
9.0 逻辑清晰
  • 请注意区分返回函数和返回值:

    def myabs():
        return abs   # 返回函数def myabs2(x):
        return abs(x)   # 返回函数调用的结果,返回值是一个数值

    查看全部
  •  sorted()函数可对list进行排序,数字从小到大,字符串默认首字母按照ASCII大小来比较

    sorted()也是一个高阶函数,它可以接收一个比较函数来实现自定义排序,比较函数的定义是,传入两个待比较的元素 x, y,如果 x 应该排在 y 的前面,返回 -1,如果 x 应该排在 y 的后面,返回 1。如果 x 和 y 相等,返回 0。

    查看全部
  • 看不懂的代码:

    def count():

        fs = []

        for i in range(1, 4):

            def f(j):

                def g():

                    return j*j

                return g

            r = f(i)

            fs.append(r)

        return fs

    f1, f2, f3 = count()

    print f1(), f2(), f3()


    查看全部
    0 采集 收起 来源:python中闭包

    2020-02-12

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

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


    查看全部
    0 采集 收起 来源:python中闭包

    2020-02-12

  • def calc_prod(lst):

        def lazy_prod():

            def f(x, y):

                return x * y

            return reduce(f, lst, 1)

        return lazy_prod

    f = calc_prod([1, 2, 3, 4])

    print f()


    查看全部
  • python中定义类方法

    和属性类似,方法也分实例方法和类方法。

    class中定义的全部是实例方法,实例方法第一个参数 self 是实例本身。

    要在class中定义类方法,需要这么写:

    class Person(object):     count = 0     @classmethod     def how_many(cls):         return cls.count     def __init__(self, name):         self.name = name         Person.count = Person.count + 1 print Person.how_many() p1 = Person('Bob') print Person.how_many()

    通过标记一个 @classmethod,该方法将绑定到 Person 类上,而非类的实例。类方法的第一个参数将传入类本身,通常将参数名命名为 cls,上面的 cls.count 实际上相当于 Person.count

    因为是在类上调用,而非实例上调用,因此类方法无法获得任何实例变量,只能获得类的引用。


    查看全部
  • 由于属性可以是普通的值对象,如 str,int 等,也可以是方法,还可以是函数,大家看看下面代码的运行结果,请想一想 p1.get_grade 为什么是函数而不是方法:

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

    这道题答案的意思是:

    练习题中的 self.get_grade 是函数没错,是函数对象,而self.get_grade() 只是函数调用,不是什么方法。

    方法指的是教程中的利用 types.MethodType 得到的self.get_grade,这才是方法,加括号就是方法调用

    p1.get_grade = types.MethodType(fn_get_grade, p1, Person)
    print p1.get_grade()

    所以很明显,方法与类有关,需要传入self (参照教程前半部分),而函数不用传入self

    练习题中的self.get_grade() 并没有传入self(你自己到 lambda 后面加一个 self 参数,看看程序会不会报错就知道了),它只是一个简单的函数调用

    所以区分方法和函数,就看需不需要传入self (加括号只是代表调用罢了。。)

    (以上均为个人观点,如有误,麻烦大佬指出)


    查看全部
  • python中方法也是属性

    我们在 class 中定义的实例方法其实也是属性,它实际上是一个函数对象:

    class Person(object):     def __init__(self, name, score):         self.name = name         self.score = score     def get_grade(self):         return 'A' p1 = Person('Bob', 90) print p1.get_grade # => <bound method Person.get_grade of <__main__.Person object at 0x109e58510>> print p1.get_grade() # => A

    也就是说,p1.get_grade 返回的是一个函数对象,但这个函数是一个绑定到实例的函数,p1.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' class Person(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

    给一个实例动态添加方法并不常见,直接在class中定义要更直观。


    查看全部
  • 打印是因为,每次创建一个实例执行一次类里面的__init__()的print Person.__count,但是如果从外面访问Person.__count是访问不了的

    查看全部
  • #创建一个函数,使它在被调用时循环变量不会被改变
    def count():
        #创建一个空列表,用来存储计算结果
        fs = []
        #使用 for...in... 循环给元素赋值,用于下面的计算
        for i in range(1,4):
            #创建一个函数,将计算的值先存储起来
            def f(X):
                #再创建一个函数,用于计算 f()函数内的元素,并返回结果
                def g():
                    return x * x
                #将计算的结果返回函数 f(x),g 是计算结果
                return g
            #调用 f()函数,将计算结果赋值给 a
            a = f(i)
            #再将 a 的值添加到空列表 fs 里
            fs.append(a)
        #最后返回 fs 列表
        return fs
    
    #给 range(1,4) 的三个元素对象进行赋值,然后将计算结果存储在 count() 函数,等候调用  
    f1,f2,f3 = count()
    #调用函数,打印结果
    print(f1(),f2(),f3())


    查看全部
    1 采集 收起 来源:python中闭包

    2020-02-12

  • #创建一个函数,计算一个列表的乘积,先存储起来,等到调用函数的时候再返回
    def calc_prod():
        def prod()
        #创建一个函数,结果返回 reduce()函数,计算乘积
        #这里的 lambda 是一个匿名函数,后面的 x,y 是函数参数,它的值等于 x*y,然后返回 lst 进行存储
            return reduce(lambda x,y: x*y,lst)
        #返回函数 prod(),等候调用
        return prod
        
    #给 f 赋值,然后调用 calc_prod()函数
    f = calc_prod([1,2,3,4)]
    #再次调用 f ,然后返回值
    print(f)


    查看全部
  • #创建一个函数,使它先计算参数内的乘积,等到调用函数的时候再返回函数本身
    
    #创建一个函数,作用是接收一个列表
    def calc_prod(lst):
        #创建一个函数,作用是存储一个列表
        def lazy_prod():
            #创建一个函数,并返回参数的乘积
            def f(x,y):
                return x * y
            #先用列表存储 lst 参数的值,等调用 f()函数的时候再返回 reduce()函数,计算函数 calc_prod(lst) 里的乘积
            return reduce(f,lst,1)
        #最后返回函数 lazy_prod,等候调用的时候再返回函数
        return lazy_prod
        
    #给函数 f()的列表赋值,将值返回函数 calc_prod(lst) 的参数 lst ,暂时存储
    f = calc_prod([1,2,3,4)]
    #调用 f()函数,计算乘积


    查看全部
  • def cmp_ignore_case(s1, s2):

        u1=s1.upper()

        u2=s2.upper()

        if u1>u2:

            return 1

        elif u1==u2:

            return 0

        else:

            return -1

    print sorted(['bob', 'about', 'Zoo', 'Credit'], cmp_ignore_case)


    查看全部
  • python中定义实例方法

    一个实例的私有属性就是以__开头的属性,无法被外部访问,那这些属性定义有什么用?

    虽然私有属性无法从外部访问,但是,从类的内部是可以访问的。除了可以定义实例的属性外,还可以定义实例的方法。

    实例的方法就是在类中定义的函数,它的第一个参数永远是 self,指向调用该方法的实例本身,其他参数和一个普通函数是完全一样的:

    class Person(object):     def __init__(self, name):         self.__name = name     def get_name(self):         return self.__name

    get_name(self) 就是一个实例方法,它的第一个参数是self。__init__(self, name)其实也可看做是一个特殊的实例方法。

    调用实例方法必须在实例上调用:

    p1 = Person('Bob') print p1.get_name()  # self不需要显式传入 # => Bob

    在实例方法内部,可以访问所有实例属性,这样,如果外部需要访问私有属性,可以通过方法调用获得,这种数据封装的形式除了能保护内部数据一致性外,还可以简化外部调用的难度。


    查看全部
  • python中类属性和实例属性名字冲突怎么办

    修改类属性会导致所有实例访问到的类属性全部都受影响,但是,如果在实例变量上修改类属性会发生什么问题呢?

    class Person(object):     address = 'Earth'     def __init__(self, name):         self.name = name p1 = Person('Bob') p2 = Person('Alice') print 'Person.address = ' + Person.address p1.address = 'China' print 'p1.address = ' + p1.address print 'Person.address = ' + Person.address print 'p2.address = ' + p2.address

    结果如下:

    Person.address = Earth p1.address = China Person.address = Earth p2.address = Earth

    我们发现,在设置了 p1.address = 'China' 后,p1访问 address 确实变成了 'China',但是,Person.address和p2.address仍然是'Earch',怎么回事?

    原因是 p1.address = 'China'并没有改变 Person 的 address,而是给 p1这个实例绑定了实例属性address ,对p1来说,它有一个实例属性address(值是'China'),而它所属的类Person也有一个类属性address,所以:

    访问 p1.address ,优先查找实例属性,返回'China'。

    访问 p2.address ,p2没有实例属性address,但是有类属性address,因此返回'Earth'。

    可见,当实例属性和类属性重名时,实例属性优先级高,它将屏蔽掉对类属性的访问。

    当我们把 p1 的 address 实例属性删除后,访问 p1.address 就又返回类属性的值 'Earth'了:

    del p1.address print p1.address # => Earth

    可见,千万不要在实例上修改类属性,它实际上并没有修改类属性,而是给实例绑定了一个实例属性


    查看全部

举报

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

微信扫码,参与3人拼团

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

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