Python note (one)

来源:互联网 发布:mac照片找不到 编辑:程序博客网 时间:2024/06/05 22:50

今天看了python的教程,遂开始记笔记。

I. 装饰器:

import functoolsdef foo(func):@functools.wraps(func)def wrapper (*args,**kw):print 'call %s():'%func.__name__return func(*args,**kw)  #1return wrapper@foodef log():  #2print '20161219'log()

此处不能用 log('xx')的形式插入参数,因为装饰器最后实现的还是被装饰函数logd()实现,它没有参数,#1处就算传入参数也会报错,如果想要

装饰器中传入参数,则1,2 都需要设定成,尤其是2需要设定至少一个参数才可。

只有一个思考题,思考一下能否写出一个@log的decorator,使它既支持:

@logdef f():    pass
又支持

@log('execute')def f():    pass

  II.偏函数(略)

III. 模块

作用域:在一个模块中,我们可能会定义很多函数和变量,但有的函数和变量我们希望给别人使用,有的函数和变量我们希望仅仅在模块内部使用。在Python中,是通过_前缀来实现的。

正常的函数和变量名是公开的(public),可以被直接引用,比如:abcx123PI等;

类似__xxx__这样的变量是特殊变量,可以被直接引用,但是有特殊用途,比如上面的__author____name__就是特殊变量,hello模块定义的文档注释也可以用特殊变量__doc__访问,我们自己的变量一般不要用这种变量名;

类似_xxx__xxx这样的函数或变量就是非公开的(private),不应该被直接引用,比如_abc__abc等;

eg:

def _private_1(name):    return 'Hello, %s' % namedef _private_2(name):    return 'Hi, %s' % namedef greeting(name):    if len(name) > 3:        return _private_1(name)    else:        return _private_2(name)

我们在模块里公开greeting()函数,而把内部逻辑用private函数隐藏起来了,这样,调用greeting()函数不用关心内部的private函数细节,这也是一种非常有用的代码封装和抽象的方法,即:

外部不需要引用的函数全部定义成private,只有外部需要引用的函数才定义为public。

IX.面向对象编程

面向对象的设计思想是抽象出Class,根据Class创建Instance。

面向对象的抽象程度又比函数要高,因为一个Class既包含数据,又包含操作数据的方法。

数据封装、继承和多态是面向对象的三大特点。

X.class

类可以自由的绑定变量,如果想便向不被访问那么:
可以把属性的名称前加上两个下划线__,在Python中,实例的变量名如果以__开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问:

class Student(object):    def __init__(self, name, score):        self.__name = name        self.__score = score    def print_score(self):        print '%s: %s' % (self.__name, self.__score)
如果还想访问其值则需要通过方法来实现.

双下划线开头的实例变量是不是一定不能从外部访问呢?其实也不是。不能直接访问__name是因为Python解释器对外把__name变量改成了_Student__name,所以,仍然可以通过_Student__name来访问__name变量:

>>> bart._Student__name'Bart Simpson'

但是强烈建议你不要这么干,因为不同版本的Python解释器可能会把__name改成不同的变量名。

总的来说就是,Python本身没有任何机制阻止你干坏事,一切全靠自觉。

XI.继承和多态

isinstance() 函数可以用来判断类型,返回 t & f  

eg:isinstace(a,list)

要理解多态的好处,我们还需要再编写一个函数,这个函数接受一个Animal类型的变量:

def run_twice(animal):    animal.run()    animal.run()

当我们传入Animal的实例时,run_twice()就打印出:

>>> run_twice(Animal())Animal is running...Animal is running...

当我们传入Dog的实例时,run_twice()就打印出:

>>> run_twice(Dog())Dog is running...Dog is running...

当我们传入Cat的实例时,run_twice()就打印出:

>>> run_twice(Cat())Cat is running...Cat is running...

看上去没啥意思,但是仔细想想,现在,如果我们再定义一个Tortoise类型,也从Animal派生:

class Tortoise(Animal):    def run(self):        print 'Tortoise is running slowly...'

当我们调用run_twice()时,传入Tortoise的实例:

>>> run_twice(Tortoise())Tortoise is running slowly...Tortoise is running slowly...

你会发现,新增一个Animal的子类,不必对run_twice()做任何修改,实际上,任何依赖Animal作为参数的函数或者方法都可以不加修改地正常运行,原因就在于多态。

多态的好处就是,当我们需要传入Dog、Cat、Tortoise……时,我们只需要接收Animal类型就可以了,因为Dog、Cat、Tortoise……都是Animal类型,然后,按照Animal类型进行操作即可。由于Animal类型有run()方法,因此,传入的任意类型,只要是Animal类或者子类,就会自动调用实际类型的run()方法,这就是多态的意思:






0 0
原创粉丝点击