python 自动化之路 day 05

内容目录:

  1. 列表生成式、迭代器&生成器
  2. 装饰器
  3. 模块初始
  4. 常用模块

1.列表生成式,迭代器&生成器

列表生成式

需求:列表[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],要求把列表里的每个值加1

你可能会想到2种方式 :

 1 >>> a
 2 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
 3 >>> b = []
 4 >>> for i in a:b.append(i+1)
 5 ...
 6 >>> b
 7 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
 8 >>> a = b
 9 >>> a
10 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

法 1

 1 >>> a
 2 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
 3 >>> a = map(lambda x:x+1, a)
 4 >>> a
 5 <map object at 0x101d2c630>
 6 >>> for i in a:print(i)
 7 ...
 8 3
 9 5
10 7
11 9
12 11

法 2

其实还有一种写法,如下

1 >>> a = [i+1 for i in range(10)]
2 >>> a
3 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

装逼版

这就叫做列表生成

生成器

通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。

所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。

要创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator:


1

2

3

4

5

6

>>> L = [x * for in range(10)]

>>> L

[0149162536496481]

>>> g = (x * for in range(10))

>>> g

<generator object <genexpr> at 0x1022ef630>

创建Lg的区别仅在于最外层的[]()L是一个list,而g是一个generator。

我们可以直接打印出list的每一个元素,但我们怎么打印出generator的每一个元素呢?

如果要一个一个打印出来,可以通过next()函数获得generator的下一个返回值:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

>>> next(g)

0

>>> next(g)

1

>>> next(g)

4

>>> next(g)

9

>>> next(g)

16

>>> next(g)

25

>>> next(g)

36

>>> next(g)

49

>>> next(g)

64

>>> next(g)

81

>>> next(g)

Traceback (most recent call last):

  File "<stdin>", line 1in <module>

StopIteration

我们讲过,generator保存的是算法,每次调用next(g),就计算出g的下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration的错误。

当然,上面这种不断调用next(g)实在是太变态了,正确的方法是使用for循环,因为generator也是可迭代对象:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

>>> g = (x * for in range(10))

>>> for in g:

...     print(n)

...

0

1

4

9

16

25

36

49

64

81

所以,我们创建了一个generator后,基本上永远不会调用next(),而是通过for循环来迭代它,并且不需要关心StopIteration的错误。

generator非常强大。如果推算的算法比较复杂,用类似列表生成式的for循环无法实现的时候,还可以用函数来实现。

比如,著名的斐波拉契数列(Fibonacci),除第一个和第二个数外,任意一个数都可由前两个数相加得到:

1, 1, 2, 3, 5, 8, 13, 21, 34, ...

斐波拉契数列用列表生成式写不出来,但是,用函数把它打印出来却很容易:


1

2

3

4

5

6

7

def fib(max):

    n, a, b = 001

    while n < max:

        print(b)

        a, b = b, a + b

        = + 1

    return ‘done‘

注意,赋值语句:


1

a, b = b, a + b

相当于:


1

2

3

= (b, a + b) # t是一个tuple

= t[0]

= t[1]

但不必显式写出临时变量t就可以赋值。

上面的函数可以输出斐波那契数列的前N个数:


1

2

3

4

5

6

7

8

9

10

11

12

>>> fib(10)

1

1

2

3

5

8

13

21

34

55

done

仔细观察,可以看出,fib函数实际上是定义了斐波拉契数列的推算规则,可以从第一个元素开始,推算出后续任意的元素,这种逻辑其实非常类似generator。

也就是说,上面的函数和generator仅一步之遥。要把fib函数变成generator,只需要把print(b)改为yield b就可以了:

def fib(max):
    n,a,b = 0,0,1

    while n < max:
        #print(b)
        yield  b
        a,b = b,a+b

        n += 1

    return ‘done‘ 

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

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

这里,最难理解的就是generator和函数的执行流程不一样。函数是顺序执行,遇到return语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。

data = fib(10)
print(data)

print(data.__next__())
print(data.__next__())
print("干点别的事")
print(data.__next__())
print(data.__next__())
print(data.__next__())
print(data.__next__())
print(data.__next__())

#输出
<generator object fib at 0x101be02b0>
1
1
干点别的事
2
3
5
8
13

在上面fib的例子,我们在循环过程中不断调用yield,就会不断中断。当然要给循环设置一个条件来退出循环,不然就会产生一个无限数列出来。

同样的,把函数改成generator后,我们基本上从来不会用next()来获取下一个返回值,而是直接使用for循环来迭代:

>>> for n in fib(6):
...     print(n)
...
1
1
2
3
5
8

但是用for循环调用generator时,发现拿不到generator的return语句的返回值。如果想要拿到返回值,必须捕获StopIteration错误,返回值包含在StopIterationvalue中:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

>>> g = fib(6)

>>> while True:

...     try:

...         x = next(g)

...         print(‘g:‘, x)

...     except StopIteration as e:

...         print(‘Generator return value:‘, e.value)

...         break

...

g: 1

g: 1

g: 2

g: 3

g: 5

g: 8

Generator return value: done

关于如何捕获错误,后面的错误处理还会详细讲解。

还可通过yield实现在单线程的情况下实现并发运算的效果  

 1 import time
 2 def consumer(name):
 3     print("%s 准备吃包子啦!" %name)
 4     while True:
 5        baozi = yield
 6
 7        print("包子[%s]来了,被[%s]吃了!" %(baozi,name))
 8
 9
10 def producer(name):
11     c = consumer(‘A‘)
12     c2 = consumer(‘B‘)
13     c.__next__()
14     c2.__next__()
15     print("老子开始准备做包子啦!")
16     for i in range(10):
17         time.sleep(1)
18         print("做了2个包子!")
19         c.send(i)
20         c2.send(i)
21
22 producer("alex")

迭代器

我们已经知道,可以直接作用于for循环的数据类型有以下几种:

一类是集合数据类型,如listtupledictsetstr等;

一类是generator,包括生成器和带yield的generator function。

这些可以直接作用于for循环的对象统称为可迭代对象:Iterable

可以使用isinstance()判断一个对象是否是Iterable对象:


1

2

3

4

5

6

7

8

9

10

11

>>> from collections import Iterable

>>> isinstance([], Iterable)

True

>>> isinstance({}, Iterable)

True

>>> isinstance(‘abc‘, Iterable)

True

>>> isinstance((x for in range(10)), Iterable)

True

>>> isinstance(100, Iterable)

False

而生成器不但可以作用于for循环,还可以被next()函数不断调用并返回下一个值,直到最后抛出StopIteration错误表示无法继续返回下一个值了。

*可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator

可以使用isinstance()判断一个对象是否是Iterator对象:


1

2

3

4

5

6

7

8

9

>>> from collections import Iterator

>>> isinstance((x for in range(10)), Iterator)

True

>>> isinstance([], Iterator)

False

>>> isinstance({}, Iterator)

False

>>> isinstance(‘abc‘, Iterator)

False

生成器都是Iterator对象,但listdictstr虽然是Iterable,却不是Iterator

listdictstrIterable变成Iterator可以使用iter()函数:


1

2

3

4

>>> isinstance(iter([]), Iterator)

True

>>> isinstance(iter(‘abc‘), Iterator)

True

你可能会问,为什么listdictstr等数据类型不是Iterator

这是因为Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。

Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。

小结

凡是可作用于for循环的对象都是Iterable类型;

凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;

集合数据类型如listdictstr等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。

Python的for循环本质上就是通过不断调用next()函数实现的,例如:


1

2

for in [12345]:

    pass

实际上完全等价于:

 1 # 首先获得Iterator对象:
 2 it = iter([1, 2, 3, 4, 5])
 3 # 循环:
 4 while True:
 5     try:
 6         # 获得下一个值:
 7         x = next(it)
 8     except StopIteration:
 9         # 遇到StopIteration就退出循环
10         break

2.装饰器

你是一家视频网站的后端开发工程师,你们网站有以下几个版块


1

2

3

4

5

6

7

8

9

10

11

def home():

    print("---首页----")

def america():

    print("----动作专区----")

def japan():

    print("----武侠专区----")

def henan():

    print("----魔幻专区----")

视频刚上线初期,为了吸引用户,你们采取了免费政策,所有视频免费观看,迅速吸引了一大批用户,免费一段时间后,每天巨大的带宽费用公司承受不了了,所以准备对比较受欢迎的几个版块收费,你拿到这个需求后,想了想,想收费得先让其进行用户认证,认证通过后,再判定这个用户是否是VIP付费会员就可以了,是VIP就让看,不是VIP就不让看就行了呗。 你觉得这个需求很是简单,因为要对多个版块进行认证,那应该把认证功能提取出来单独写个模块,然后每个版块里调用 就可以了,与是轻轻的就实现了下面的功能 。


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

#_*_coding:utf-8_*_

user_status = False #用户登录了就把这个改成True

def login():

    _username = "alex" #假装这是DB里存的用户信息

    _password = "abc!23" #假装这是DB里存的用户信息

    global user_status

    if user_status == False:

        username = input("user:")

        password = input("pasword:")

        if username == _username and password == _password:

            print("welcome login....")

            user_status = True

        else:

            print("wrong username or password!")

    else:

        print("用户已登录,验证通过...")

def home():

    print("---首页----")

def america():

    login() #执行前加上验证

    print("----欧美专区----")

def japan():

    print("----日韩专区----")

def henan():

    login() #执行前加上验证

    print("----河南专区----")

home()

america()

henan()

此时你信心满满的把这个代码提交给你的TEAM LEADER审核,没成想,没过5分钟,代码就被打回来了, TEAM LEADER给你反馈是,我现在有很多模块需要加认证模块,你的代码虽然实现了功能,但是需要更改需要加认证的各个模块的代码,这直接违反了软件开发中的一个原则“开放-封闭”原则,简单来说,它规定已经实现的功能代码不允许被修改,但可以被扩展,即:

  • 封闭:已实现的功能代码块
  • 开放:对扩展开发

这个原则你还是第一次听说,我擦,再次感受了自己这个野生程序员与正规军的差距,BUT ANYWAY,老大要求的这个怎么实现呢?如何在不改原有功能代码的情况下加上认证功能呢?

高阶函数,就是把一个函数当做一个参数传给另外一个函数,我只需要写个认证方法,每次调用 需要验证的功能 时,直接 把这个功能 的函数名当做一个参数 传给 我的验证模块不就行了么


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

#_*_coding:utf-8_*_

user_status = False #用户登录了就把这个改成True

def login(func): #把要执行的模块从这里传进来

    _username = "alex" #假装这是DB里存的用户信息

    _password = "abc!23" #假装这是DB里存的用户信息

    global user_status

    if user_status == False:

        username = input("user:")

        password = input("pasword:")

        if username == _username and password == _password:

            print("welcome login....")

            user_status = True

        else:

            print("wrong username or password!")

    if user_status == True:

        func() # 看这里看这里,只要验证通过了,就调用相应功能

def home():

    print("---首页----")

def america():

    #login() #执行前加上验证

    print("----欧美专区----")

def japan():

    print("----日韩专区----")

def henan():

    #login() #执行前加上验证

    print("----河南专区----")

home()

login(america) #需要验证就调用 login,把需要验证的功能 当做一个参数传给login

# home()

# america()

login(henan)

你很开心,终于实现了老板的要求,不改变原功能代码的前提下,给功能加上了验证

你改变了调用方式呀, 想一想,现在没每个需要认证的模块,都必须调用你的login()方法,并把自己的函数名传给你,人家之前可不是这么调用 的, 试想,如果 有100个模块需要认证,那这100个模块都得更改调用方式,这么多模块肯定不止是一个人写的,让每个人再去修改调用方式 才能加上认证

但问题是,如何即不改变原功能代码,又不改变原有调用方式,还能加上认证呢?

学过匿名函数没有?


1

2

3

4

def plus(n):

    return n+1

plus2 = lambda x:x+1

上面这两种写法是不是代表 同样的意思?

我给lambda x:x+1 起了个名字叫plus2,是不是相当于def plus2(x) ?

给函数赋值变量名就像def func_name 是一样的效果,如下面的plus(n)函数,你调用时可以用plus名,还可以再起个其它名字,如


1

2

3

calc = plus

calc(n)

之前写的下面这段调用 认证的代码


1

2

3

4

5

home()

login(america) #需要验证就调用 login,把需要验证的功能 当做一个参数传给login

# home()

# america()

login(henan)

你之所改变了调用方式,是因为用户每次调用时需要执行login(henan),类似的。其实稍一改就可以了呀


1

2

3

home()

america = login(america)

henan = login(henan)

这样你,其它人调用henan时,其实相当于调用了login(henan), 通过login里的验证后,就会自动调用henan功能。

那用户调用时,应该是下面这个样子


1

2

3

4

5

6

home()

america = login(america) #你在这里相当于把america这个函数替换了

henan = login(henan)

#那用户调用时依然写

america()

但问题在于,还不等用户调用 ,你的america = login(america)就会先自己把america执行了

想实现一开始你写的america = login(america)不触发你函数的执行,只需要在这个login里面再定义一层函数,第一次调用america = login(america)只调用到外层login,这个login虽然会执行,但不会触发认证了,因为认证的所有代码被封装在login里层的新定义 的函数里了,login只返回 里层函数的函数名,这样下次再执行america()时, 就会调用里层函数啦。。。


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

def login(func): #把要执行的模块从这里传进来

    def inner():#再定义一层函数

        _username = "alex" #假装这是DB里存的用户信息

        _password = "abc!23" #假装这是DB里存的用户信息

        global user_status

        if user_status == False:

            username = input("user:")

            password = input("pasword:")

            if username == _username and password == _password:

                print("welcome login....")

                user_status = True

            else:

                print("wrong username or password!")

        if user_status == True:

            func() # 看这里看这里,只要验证通过了,就调用相应功能

    return inner #用户调用login时,只会返回inner的内存地址,下次再调用时加上()才会执行inner函数

这是开发中一个常用的玩法,叫语法糖,官方名称“装饰器”,其实上面的写法,还可以更简单

可以把下面代码去掉


1

america = login(america) #你在这里相当于把america这个函数替换了

只在你要装饰的函数上面加上下面代码


1

2

3

4

5

6

7

8

9

10

11

12

@login

def america():

    #login() #执行前加上验证

    print("----欧美专区----")

def japan():

    print("----日韩专区----")

@login

def henan():

    #login() #执行前加上验证

    print("----河南专区----")

效果是一样的。

给你的“河南专区”版块 加了个参数,然后,结果 出错了。

怎么传个参数就不行了呢?

你调用henan时,其实是相当于调用的login,你的henan第一次调用时henan = login(henan), login就返回了inner的内存地址,第2次用户自己调用henan("3p"),实际上相当于调用的时inner,但你的inner定义时并没有设置参数,但你给他传了个参数,所以自然就报错了

最终,你终于搞定了所有需求,完全遵循开放-封闭原则,最终代码如下 。

第二2天早上,产品经理又提了新的需求,要允许用户选择用qq\weibo\weixin认证,此时的你,已深谙装饰器各种装逼技巧,轻松的就实现了新的需求。

 1 user_status = False
 2 def login(authtype):
 3     def outer(func):
 4         def inter():
 5             if authtype == ‘qq‘:
 6                 _username = ‘yang‘
 7                 _password = ‘abc123‘
 8                 global  user_status
 9
10                 if user_status == False:
11                     username = input("username: ")
12                     password = input("password: ")
13
14                     if username == _username and password == _password:
15                         print("欢迎你,尊敬的VIP 。 ")
16                         user_status = True
17                     else:
18                         print("用户名或密码错误。 ")
19                 if user_status == True:
20                     func()
21             else:
22                 print("仅支持QQ。  ")
23         return  inter
24     return outer
25 def home():
26     print("---首页---")
27 @login(‘qq‘)
28 def amercia():
29     print("---欧美专区---")
30
31 def japan():
32     print("---日韩专区---")
33 @login(‘weixin‘)
34 def henan():
35     print("---河南专区---")
36
37
38 home()
39 amercia()
40 japan()
41 henan()

3.模块初始

模块,用一砣代码实现了某个功能的代码集合。

类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合。而对于一个复杂的功能来,可能需要多个函数才能完成(函数又可以在不同的.py文件中),n个 .py 文件组成的代码集合就称为模块。

如:os 是系统相关的模块;file是文件操作相关的模块

模块分为三种:

  • 自定义模块
  • 内置标准模块(又称标准库)
  • 开源模块 (https://pypi.python.org/pypi)

如何在py文件中引入自定义模块?

import os

from os import time

通过:

1 for i in sys.path:
2     print(i)

我们可以得到模块路径。

在pycharm中自动帮我们把pychram的路径加进去了。

但是在windows 系统执行的时候是不会把pychram的路径加进去的。

这时候我们需要手工添加进去:

1 import  sys
2 import  os
3 BaseDir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
4 # #__file__是取文件的相对路径
5 # os.path.abspath()是取文件的绝对路径
6 # os.path.dirname()是取文件的上级路径
7 sys.path.append(BaseDir)

python2中

目录里没有__init__,那就只是一个目录,目录是不可以被导入的。

有__init__,那这个目录就变成了包 = "package"

no matter py2 or py3 , only the package can be imported

howere, in py 3 ,the directory will also be treated as package,

__init__.pi in py3 is not mandatory.

4.常用模块

提供对操作系统进行调用的接口:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径

os.chdir("dirname")  改变当前脚本工作目录;相当于shell下cd

os.curdir  返回当前目录: (‘.‘)

os.pardir  获取当前目录的父目录字符串名:(‘..‘)

os.makedirs(‘dirname1/dirname2‘)    可生成多层递归目录

os.removedirs(‘dirname1‘)    若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推

os.mkdir(‘dirname‘)    生成单级目录;相当于shell中mkdir dirname

os.rmdir(‘dirname‘)    删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname

os.listdir(‘dirname‘)    列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印

os.remove()  删除一个文件

os.rename("oldname","newname")  重命名文件/目录

os.stat(‘path/filename‘)  获取文件/目录信息

os.sep    输出操作系统特定的路径分隔符,win下为"\\",Linux下为"/"

os.linesep    输出当前平台使用的行终止符,win下为"\t\n",Linux下为"\n"

os.pathsep    输出用于分割文件路径的字符串

os.name    输出字符串指示当前使用平台。win->‘nt‘; Linux->‘posix‘

os.system("bash command")  运行shell命令,直接显示

os.environ  获取系统环境变量

os.path.abspath(path)  返回path规范化的绝对路径

os.path.split(path)  将path分割成目录和文件名二元组返回

os.path.dirname(path)  返回path的目录。其实就是os.path.split(path)的第一个元素

os.path.basename(path)  返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素

os.path.exists(path)  如果path存在,返回True;如果path不存在,返回False

os.path.isabs(path)  如果path是绝对路径,返回True

os.path.isfile(path)  如果path是一个存在的文件,返回True。否则返回False

os.path.isdir(path)  如果path是一个存在的目录,则返回True。否则返回False

os.path.join(path1[, path2[, ...]])  将多个路径组合后返回,第一个绝对路径之前的参数将被忽略

os.path.getatime(path)  返回path所指向的文件或者目录的最后存取时间

os.path.getmtime(path)  返回path所指向的文件或者目录的最后修改时间

时间: 2024-10-27 07:34:14

python 自动化之路 day 05的相关文章

《Python自动化之路》大纲

第一天 1.编程语言介绍2.Python基础,介绍历史.发展情况及现状3.Python安装.环境准备4.编程风格.语法要求.变量格式等5.编写用户交互脚本6.读取用户输入7.基本流程控制,if..else/for x in…/while True8.程序流程控制二,break\continue\ 嵌套循环9.项目实践:编写用户登录认证程序* 实现用户名密码登陆,输入错误3次后锁定用户,多用户在线! 第二天1.python I/O交互2.处理文件.通过Python修改及处理文件内容3.项目实践:编

python 自动化之路 logging日志模块

logging 日志模块 http://python.usyiyi.cn/python_278/library/logging.html 中文官方http://blog.csdn.net/zyz511919766/article/details/25136485 清晰明了,入门必备http://my.oschina.net/leejun2005/blog/126713 继承讲的很棒http://my.oschina.net/u/126495/blog/464892 实例分析 一:概述 在实际项目

Python学习之路——基础05篇

在python中,也分全局变量和局部变量,但是据我所知,如果在if中定义的变量是属于往下的全局变量,python中也有函数的定义和返回,通常定义一个函数是: def 函数名(参数1,参数2,...): 函数体 return x 当然,不要参数也是可以的,如果不写return则默认返回空,而在函数内是不能修改全局变量的值的,而如果你想要给函数外的全局变量赋值,你则要使用global语句说明这个变量是全局变量.否则就会出错.但是,如果不需要给全局变量重新赋值,则可以不使用global语句,但是,使用

python 自动化之路 day 10

本节内容 Gevent协程 Select\Poll\Epoll异步IO与事件驱动 Python连接Mysql数据库操作 RabbitMQ队列 Redis\Memcached缓存 Paramiko SSH Twsited网络框架 引子 到目前为止,我们已经学了网络并发编程的2个套路, 多进程,多线程,这哥俩的优势和劣势都非常的明显,我们一起来回顾下 协程 协程,又称微线程,纤程.英文名Coroutine.一句话说明什么是线程:协程是一种用户态的轻量级线程. 协程拥有自己的寄存器上下文和栈.协程调度

python 自动化之路 day 07

本节内容: 面向对象编程介绍 为什么要用面向对象进行开发? 面向对象的特性:封装.继承.多态 类.方法. 引子 你现在是一家游戏公司的开发人员,现在需要你开发一款叫做<人狗大战>的游戏,你就思考呀,人狗作战,那至少需要2个角色,一个是人, 一个是狗,且人和狗都有不同的技能,比如人拿棍打狗, 狗可以咬人,怎么描述这种不同的角色和他们的功能呢? 你搜罗了自己掌握的所有技能,写出了下面的代码来描述这两个角色 + 上面两个方法相当于造了两个模子,游戏开始,你得成一个人和狗的实际对象吧,怎么生成呢? +

python 自动化之路 day 18 前端内容回顾、补充/Django安装、创建

前端回顾: 整体: - HTML - CSS - JavaScript - 基本数据类型 - for,while.. - DOM - obj = document.getElementById('..') - obj.innerHtml - BOM: - setInterval... ----> 可以完成所有操作 <---- - jQuery: - 选择器 $('#') $('.') - 筛选器 $('#').find('') - 内容或属性 - $('#i1').val() input系列,

python 自动化之路 day 06

ATM作业讲解: 数据访问层 业务逻辑层 time & datetime模块 1 import time 2 3 4 # print(time.clock()) #返回处理器时间,3.3开始已废弃 , 改成了time.process_time()测量处理器运算时间,不包括sleep时间,不稳定,mac上测不出来 5 # print(time.altzone) #返回与utc时间的时间差,以秒计算\ 6 # print(time.asctime()) #返回时间格式"Fri Aug 19

python 自动化之路 day 09 进程、线程、协程篇

本节内容 操作系统发展史介绍 进程.与线程区别 python GIL全局解释器锁 线程 语法 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Event事件 queue队列 生产者消费者模型 Queue队列 开发一个线程池 进程 语法 进程间通讯 进程池

python 自动化之路 day 14

今日内容 http://www.cnblogs.com/wupeiqi/articles/5699254.html 群共享 s15Html课件 1. paramiko模块 https://github.com/paramiko/paramiko/blob/master/demos/interactive.py 2. 实现跳板机 作业:数据库+paramiko实现 3. HTML 在服务器端就是一个文件,文件内部: <h1>内容</h1> <h2>内容</h2>