学习廖雪峰python3教程(1)

本网站用的阿里云ECS,推荐大家用。自己搞个学习研究也不错
  1. “//” 是地板除。 如5//3=1
  2. 字符串编码ascii->unicode->utf-8(gbk)。 unicode是个中间编码,在内存中使用。显示和存到文件或者传输时是需要编码成utf-8或者gbk编码的,这样可以减少数据传输量。
    >>>ord(‘A’)//65, 或者字符的整数表示。这里需要注意的是,python用的是unicode编码,也就是说这里的整数是指unicode编码下,对应字符的整数表示。
    >>>chr(65)//或者整数对应的字符。
    >>>’中文’.encode(‘utf-8′)// 把unicode的’中文’按utf-8编码的字节是啥。
    >>>b’\xe4\xb8\xad\xe6\x96\x87’.decode(‘utf-8’);//把’\xe4\xb8\xad\xe6\x96\x87’按utf-8解码成unicode。
  3. 函数的参数有必填参数、默认参数、可变参数、关键字参数、命名关键字参数。
    1.默认参数
    默认参数有个最大的坑,演示如下:

    先定义一个函数,传入一个list,添加一个END再返回:

    def add_end(L=[]):
    L.append(‘END’)
    return L
    当你正常调用时,结果似乎不错:

    >>> add_end([1, 2, 3])
    [1, 2, 3, 'END']
     >>> add_end(['x', 'y', 'z'])
    ['x', 'y', 'z', 'END']
    

    当你使用默认参数调用时,一开始结果也是对的:

     >>> add_end()
    ['END']
    

    但是,再次调用add_end()时,结果就不对了:

     >>> add_end()
    ['END', 'END']
     >>> add_end()
    ['END', 'END', 'END']
    

    很多初学者很疑惑,默认参数是[],但是函数似乎每次都“记住了”上次添加了’END’后的list。

    原因解释如下:

    Python函数在定义的时候,默认参数L的值就被计算出来了,即[],因为默认参数L也是一个变量,它指向 对象[],每次调用该函数,如果改变了L的内容,则下次调用时,默认参数的内容就变了,不再是函数定义时 的[]了。

    所以,定义默认参数要牢记一点:默认参数必须指向不变对象!
    1.可变参数
    其中可变参数可以直接把一个元组传进去。

    def test(arg1,arg2,*argn):
          print(arg1) 
    

    arg=(3,4,5)
    test(1,2,*arg)
    argn在函数内部是一个元组。

    2.关键字参数
    感觉和可变参数很像,区别是关键字参数需要传参时指定key

    def test(arg1,**argn);
          print(arg1, argn)
    

    是这么调用的test('a',name="go2live",site="演道网")
    在函数内部变成了一个dict。

    3.命名关键字参数。
    这个我感觉其实和必填参数和默认参数类似。区别是必填参数是有参数位置的。必须按位置来。
    而全名关键字参数因为指定了名字,所以位置不太重要了。

    def test(key1,*,key2,key3):
      print(key1,key2,key3)
    

    之所以多了个,是为了区别key1,key2,key3。之前的是必填参数,*之后是的命名关键字参数。
    调用如下
    test(“key1″,key2=”key2″,key3=”key3″)
    4.组合使用
    在Python中定义函数,可以用必选参数、默认参数、可变参数、关键字参数和命名关键字参数,这5种 参数都可以组合使用。但是请注意,参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键 字参数和关键字参数。
    其实这里有个小窍门,必选参数、默认参数、可变参数 都是位置相关的参数,命名关键 字参数和关键字参数 因为有关键字指定,是位置无关的。所以肯定是位置参数在前,关键字参数在后。
    又因为命名关键字参数是必传的,关键字参数是选传的。必传的在前。这样一理解就可以记忆了。

    最终可以发现,所以函数调用都可以用元组和字典来调用。元组就是位置参数。字典就是关键字参数。
    形如下面的调用方式。
    arg1=(pos1,pos2,…)
    arg2=(key1=”,key2=”,…)
    test(arg1,*arg2)

  4. 生成器。
    要创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator:
>>> L = [x * x for x in range(10)]
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g = (x * x for x in range(10))
>>> g
<generator object <genexpr> at 0x1022ef630>

第二种方法

def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a + b
        n = n + 1
    return 'done'

这就是定义generator的另一种方法。如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator:

>>> f = fib(6)
>>> f
<generator object fib at 0x104feaaa0>

这里,最难理解的就是generator和函数的执行流程不一样。函数是顺序执行,遇到return语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。
5. 装饰器
本质上,decorator就是一个返回函数的高阶函数。所以,我们要定义一个能打印日志的decorator,可以定义如下:

def log(func):
    def wrapper(*args, **kw):
        print('call %s():' % func.__name__)
        return func(*args, **kw)
    return wrapper

观察上面的log,因为它是一个decorator,所以接受一个函数作为参数,并返回一个函数。我们要借助Python的@语法,把decorator置于函数的定义处:

@log
def now():
    print('2015-3-25')

调用now()函数,不仅会运行now()函数本身,还会在运行now()函数前打印一行日志:

>>> now()
call now():
2015-3-25

把@log放到now()函数的定义处,相当于执行了语句:

now = log(now)

6.偏函数
functools.partial就是帮助我们创建一个偏函数的,不需要我们自己定义int2(),可以直接使用下面的代码创建一个新的函数int2:

>>> import functools
>>> int2 = functools.partial(int, base=2)
>>> int2('1000000')
64
>>> int2('1010101')
85

所以,简单总结functools.partial的作用就是,把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单。

未经允许不得转载:演道网 » 学习廖雪峰python3教程(1)

赞 (1)
分享到:更多 ()

评论 0

评论前必须登录!

登陆 注册