python入门之函数调用第三关函数与函数调用分清主次_第三章:Python基础の函数和文件操作实战...

本文介绍了Python中的Set集合,包括创建、功能和常见操作,如添加、更新、查找、删除等。此外,还讲解了lambda表达式的使用,并探讨了文件操作的各种方法,如读写、追加、定位等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本課主題

Set 集合和操作实战

函数介紹和操作实战

参数的深入介绍和操作实战

format 函数操作实战

lambda 表达式介绍

文件操作函数介紹和操作实战

本周作业

Set 集合和操作实战

Set 是一个无序且不容许重复的序列

创建集合有两种方式:

第一种是通过直接创建、例如:s = {11,22}

ContractedBlock.gif

ExpandedBlockStart.gif

1 >>> se = {11,222,11,222}2 >>> print(se)3 {11, 222}4 >>>type(se)5

创建集合 方法一

第二种是通过转换。从一个可迭代类型的数组、元组转换成集合 Set。例如:s = Set(list)

ContractedBlock.gif

ExpandedBlockStart.gif

1 >>> li = [11,22,11,33,11,44,55]2 >>> se = set(li) #把列表转换成集合

3 >>>se4 {33, 11, 44, 22, 55}5 >>>type(se)6

创建集合 方法二

原理:在调用 Set 函数时,它会自动调用 __intit__ 方法,这叫构造方法 ,其实内部会执行一个 For 循环,循环这个"可迭代对象"里的所有元素,一个一个添加到集合里(什么是构造方法会在后期学到面向对象后再分享)

Set 集合的功能

这是Set 集合在 Python3.5.2的源码,我把它贴进来,里面有很多双下划线的方法,现在我都不知道是什么,让我了解后会回来补充一下。现在最主要的是要了解下面这几个集合的功能:我把它归类为添加、更新、找不同、找相同、删除和返回Boolean值六大类。

ContractedBlock.gif

ExpandedBlockStart.gif

classset(object):"""set() -> new empty set object

set(iterable) -> new set object

Build an unordered collection of unique elements."""

def add(self, *args, **kwargs): #real signature unknown

"""Add an element to a set.

This has no effect if the element is already present."""

pass

def clear(self, *args, **kwargs): #real signature unknown

"""Remove all elements from this set."""

pass

def copy(self, *args, **kwargs): #real signature unknown

"""Return a shallow copy of a set."""

pass

def difference(self, *args, **kwargs): #real signature unknown

"""Return the difference of two or more sets as a new set.

(i.e. all elements that are in this set but not the others.)"""

pass

def difference_update(self, *args, **kwargs): #real signature unknown

"""Remove all elements of another set from this set."""

pass

def discard(self, *args, **kwargs): #real signature unknown

"""Remove an element from a set if it is a member.

If the element is not a member, do nothing."""

pass

def intersection(self, *args, **kwargs): #real signature unknown

"""Return the intersection of two sets as a new set.

(i.e. all elements that are in both sets.)"""

pass

def intersection_update(self, *args, **kwargs): #real signature unknown

"""Update a set with the intersection of itself and another."""

pass

def isdisjoint(self, *args, **kwargs): #real signature unknown

"""Return True if two sets have a null intersection."""

pass

def issubset(self, *args, **kwargs): #real signature unknown

"""Report whether another set contains this set."""

pass

def issuperset(self, *args, **kwargs): #real signature unknown

"""Report whether this set contains another set."""

pass

def pop(self, *args, **kwargs): #real signature unknown

"""Remove and return an arbitrary set element.

Raises KeyError if the set is empty."""

pass

def remove(self, *args, **kwargs): #real signature unknown

"""Remove an element from a set; it must be a member.

If the element is not a member, raise a KeyError."""

pass

__hash__ =Nonedef symmetric_difference(self, *args, **kwargs): #real signature unknown

"""Return the symmetric difference of two sets as a new set.

(i.e. all elements that are in exactly one of the sets.)"""

pass

def symmetric_difference_update(self, *args, **kwargs): #real signature unknown

"""Update a set with the symmetric difference of itself and another."""

pass

def union(self, *args, **kwargs): #real signature unknown

"""Return the union of sets as a new set.

(i.e. all elements that are in either set.)"""

pass

def update(self, *args, **kwargs): #real signature unknown

"""Update a set with the union of itself and others."""

pass

def __and__(self, *args, **kwargs): #real signature unknown

"""Return self&value."""

pass

def __contains__(self, y): #real signature unknown; restored from __doc__

"""x.__contains__(y) <==> y in x."""

pass

def __eq__(self, *args, **kwargs): #real signature unknown

"""Return self==value."""

pass

def __getattribute__(self, *args, **kwargs): #real signature unknown

"""Return getattr(self, name)."""

pass

def __ge__(self, *args, **kwargs): #real signature unknown

"""Return self>=value."""

pass

def __gt__(self, *args, **kwargs): #real signature unknown

"""Return self>value."""

pass

def __iand__(self, *args, **kwargs): #real signature unknown

"""Return self&=value."""

pass

def __init__(self, seq=()): #known special case of set.__init__

"""set() -> new empty set object

set(iterable) -> new set object

Build an unordered collection of unique elements.

# (copied from class doc)"""

pass

def __ior__(self, *args, **kwargs): #real signature unknown

"""Return self|=value."""

pass

def __isub__(self, *args, **kwargs): #real signature unknown

"""Return self-=value."""

pass

def __iter__(self, *args, **kwargs): #real signature unknown

"""Implement iter(self)."""

pass

def __ixor__(self, *args, **kwargs): #real signature unknown

"""Return self^=value."""

pass

def __len__(self, *args, **kwargs): #real signature unknown

"""Return len(self)."""

pass

def __le__(self, *args, **kwargs): #real signature unknown

"""Return self<=value."""

pass

def __lt__(self, *args, **kwargs): #real signature unknown

"""Return self

pass@staticmethod#known case of __new__

def __new__(*args, **kwargs): #real signature unknown

"""Create and return a new object. See help(type) for accurate signature."""

pass

def __ne__(self, *args, **kwargs): #real signature unknown

"""Return self!=value."""

pass

def __or__(self, *args, **kwargs): #real signature unknown

"""Return self|value."""

pass

def __rand__(self, *args, **kwargs): #real signature unknown

"""Return value&self."""

pass

def __reduce__(self, *args, **kwargs): #real signature unknown

"""Return state information for pickling."""

pass

def __repr__(self, *args, **kwargs): #real signature unknown

"""Return repr(self)."""

pass

def __ror__(self, *args, **kwargs): #real signature unknown

"""Return value|self."""

pass

def __rsub__(self, *args, **kwargs): #real signature unknown

"""Return value-self."""

pass

def __rxor__(self, *args, **kwargs): #real signature unknown

"""Return value^self."""

pass

def __sizeof__(self): #real signature unknown; restored from __doc__

"""S.__sizeof__() -> size of S in memory, in bytes"""

pass

def __sub__(self, *args, **kwargs): #real signature unknown

"""Return self-value."""

pass

def __xor__(self, *args, **kwargs): #real signature unknown

"""Return self^value."""

pass

__hash__ = None

Set集合的源码

添加: add( ), unions( )

更新: difference_update( ), symmeteric_difference_update( ), intersection_update( ), update( )

找不同: difference( ), symmeteric_difference( ),

找相同: intersection( )

删除: discard( ), remove( ), clear( ), pop( )

返回Boolean值: isdisjoint( ), issuperset( )

添加:add()

ContractedBlock.gif

ExpandedBlockStart.gif

1 >>> se = set() #创建空集合

2 >>>se3 set()4 >>> se.add(123) #添加123到集合里

5 >>>se6 {123}

集合功能:添加

清除所有在集合里的内容:clear()

ContractedBlock.gif

ExpandedBlockStart.gif

1 >>> se = set() #创建一个空集合

2 >>> se.add(111)3 >>> se.add(222)4 >>> se.add(333)5 >>> print(se)6 {333, 222, 111}7 >>> se.clear() #清除集合里的所有元素

8 >>>se9 set()

集合功能:删除

对比两个集合,找其中一方的不同,相当于 database 里的 left outer join: difference()

1005794-20160828195418543-1190077685.png

ContractedBlock.gif

ExpandedBlockStart.gif

1 >>> s1 = {11,22,33}2 >>> s2 = {22,33,44}3 >>> s3 = s1.difference(s2) #在s1中存在, s2中不存在

4 >>>s15 {33, 11, 22}6 >>>s37 {11}8 >>> s3 = s2.difference(s1) #在s2中存在, s1中不存在

9 >>>s310 {44}

集合功能:找不同

对比两个集合,取出双方不同的元素:symmetric_difference()

ContractedBlock.gif

ExpandedBlockStart.gif

1 >>> s1 = {11,22,33}2 >>> s2 = {22,33,44}3 >>> s3 = s1.symmetric_difference(s2) #找出双方都不存在的元素

4 >>>s15 {33, 11, 22}6 >>>s37 {11, 44}

集合功能:找不同

更新: 对比两个集合,找其中一方的不同,然后直接把结果更新到原来的集合:difference_update()

ContractedBlock.gif

ExpandedBlockStart.gif

1 >>> a = {11,22,33}2 >>> b = {22,33,44}3 >>> a.difference_update(b) #对比两个集合,找其中一方的不同,然后直接把结果更新到原来的集合

4 >>>a5 {11}

集合功能:更新

更新: 对比两个集合,取出双方不同的元素,然后直接把结果更新到原来的集合:symmetric_difference_update()

ContractedBlock.gif

ExpandedBlockStart.gif

1 >>> a = {11,22,33}2 >>> b = {22,33,44}3 >>>a.symmetric_difference_update(b)4 >>>a5 {11, 44}

集合功能:更新

刪除指定元素,不存在,不報錯!!:discard()

ContractedBlock.gif

ExpandedBlockStart.gif

1 >>> s1 = {11,22,33}2 >>> s2 = {22,33,44}3 >>> s1.discard(11)4 >>>s15 {33, 22}

集合功能:删除

刪除指定元素,不存在,報錯!!!:remove()

ContractedBlock.gif

ExpandedBlockStart.gif

1 >>> s1 = {11,22,33}2 >>> s2 = {22,33,44}3 >>> s1.remove(11)4 >>>s15 {33, 22}6 >>> s1.remove(1111)7 Traceback (most recent call last):8 File "", line 1, in

9 KeyError: 1111

集合功能:删除

随机移取某个元素并获取这个元素:pop()

ContractedBlock.gif

ExpandedBlockStart.gif

1 >>> s1 = {11,22,33}2 >>> s2 = {22,33,44}3 >>> ret =s1.pop()4 >>>ret5 33

集合功能:删除

对比两个集合,找双方交集部份,相当于 database 里的 inner join:intersection()

ContractedBlock.gif

ExpandedBlockStart.gif

1 >>> s1 = {11,22,33}2 >>> s2 = {22,33,44}3 >>> s3 = s1.intersection(s2) #找s1和s2相同的元素

4 >>>s35 {33, 22}6 >>>s17 {33, 11, 22}

集合功能:找相同

对比两个集合,找双方交集部份,相当于 database 里的 inner join,然后直接把结果更新到原来的集合:intersection_update()

ContractedBlock.gif

ExpandedBlockStart.gif

1 >>> s1 = {11,22,33}2 >>> s2 = {22,33,44}3 >>> s1.intersection_update(s2) #找相同然后直接更新 s1

4 >>>s15 {33, 22}

集合功能:找相同然后更新

判断两个集合有没有交集部份,如果有便返回 False ;如果没有,则返回 True:isdisjoint()

ContractedBlock.gif

ExpandedBlockStart.gif

1 >>> s1 = {11,22,33}2 >>> s2 = {22,33,44}3 >>> s1.isdisjoint(s2) #有交集部分

4 False5

6 >>> s1 = {11,55,66}7 >>> s2 = {22,33,44}8 >>> s1.isdisjoint(s2) #没有交集部分

9 True

集合功能:返回Boolean值

判断两个集合有没有父子关系,有是 True, 沒有則 False:issuperset()

ContractedBlock.gif

ExpandedBlockStart.gif

1 >>> s1 = {11,22,33}2 >>> s2 = {22,33,44}3 >>> s1.issuperset(s2) #s1 不是 s2 的父序列

4 False5 >>>

6 >>> s1 = {11,22,33}7 >>> s2 = {22,33}8 >>> s1.issuperset(s2) #s1 是 s2 的父序列

9 True

集合功能:返回Boolean值

把两个集合连合然后去掉重覆的就是并集(这功能相当于 database, union 然后拿distinct value):union()

ContractedBlock.gif

ExpandedBlockStart.gif

1 >>> s1 = {11,22,33}2 >>> s2 = {22,33,44}3 >>> s3 =s1.union(s2)4 >>>s35 {33, 22, 11, 44}

集合功能:添加

批量地把一托集合增加到目标集合,update()接收一个可以被迭代的对象 e.g. List、Tuple、String:update()

ContractedBlock.gif

ExpandedBlockStart.gif

1 >>> s1 = {11,22,33}2 >>> s2 = {22,33,44}3 >>> s1.update({77,88,99})4 >>>s15 {33, 99, 22, 88, 11, 77}6 >>>s1.update(s2)7 >>>s18 {33, 99, 22, 88, 11, 44, 77}9 >>>

集合功能:更新

difference( ) 和 difference_update( ) 的应用:

s1 集合和 s2 集合的结果会保持不变,两个方法 difference() 和 symmetric_difference() 都会产生一个新的集合,所以在实际情景中如果需要重用 s1 和 s2 集合的时候,就不要用 differernce_updates() 和 symmetric_difference_update() 了。因为这两个函数会覆盖本來在 s1 里的结果。

如果以后不需要基於 s1 來操作,只需要拿最新结果的话,就可以用 differernce_updates() 和 symmetric_difference_update(),这里的好处是变量声明减少了就可以​​节省内存空间! ! !

案例实战

[更新中...]

函数介紹和操作实战

在还没有学函数之前,我们实现的代码是用很多条件判断(If-then-else)还有表达式的For 循环来实现功能,不免有很多重覆性的代码,其实这个过程叫"面向过程编程”,就是从上到下按照逻辑一点一点去写,如果遇到重覆的功能,最典型的操作就是复制和粘贴(Copy and Paste)

面向过程编程的缺点:

如果代码量多的话,不断的复制和粘贴,会导致代码缺乏了可阅读性;

不断使用重覆代码,代码量多,程序员也会很累,会导致代码缺乏了重用性。

**总结:基于以上两点的解决方安案是运用函数式编程!!函数是用来封装某些功能的,它的出现是为了增加代码的重用性,令代码更简洁,而且可以增加其可读性,以后如果要使用的话就直接调用这个函数就行啦! !

创建函数的步骤如下:

用def关键字来声明这是一个函数;

在 def 後面加一個空格,然后寫上一個名字代表函数名稱,以后就可以在内存里调用它;

名字加上后再加一个括号( );

然后在函数体里写上函数的内容:就是具体需要实现的功能;

然后加上返回值,如果沒有返回值的話 Python 会有一个默应的返回值 (None)

ContractedBlock.gif

ExpandedBlockStart.gif

>>> deffunc():

...print("123")

...>>> f1 =func()123

>>> print("f1:",f1)

f1: None

沒有返回值

有返回值的意思是:函数可以被調用然後賦值到另外一個參數,也就是說一個函数可以像參數一樣被传递。

ContractedBlock.gif

ExpandedBlockStart.gif

>>> deffunc():

...return "123"...>>> f1 =func()>>> print("f1:",f1)

f1:123

有返回值

函数可以在括号里面输入参数。

案例实战

以下是一个发邮件的函数,把登录邮件和发邮件这个功能封装在一个叫 sendMail()的函数里,只要一调用这个功能,它就会运行同一样的代码来发送邮件,这就是函数。

ContractedBlock.gif

ExpandedBlockStart.gif

defsendMail():importsmtplibfrom email.mime.text importMIMETextfrom email.utils importformataddr

msg= MIMEText("Python Email testing",'plain','utf-8')

msg['From'] = formataddr(["Janice", "janicecheng.python@gmail.com"])

msg['To'] = formataddr(["Janice", "janicecheng.python@gmail.com"])

msg['Subject']='主題'server= smtplib.SMTP("smtp.gmail.com", 587)

server.starttls()

server.login("janicecheng.python@gmail.com","password")

server.sendmail("janicecheng.python@gmail.com",["janicecheng.python@gmail.com",], msg.as_string())print("Mail Send Successfully")

server.quit()

sendMail()

邮件发送函数代码

def sendMail( ): 这叫声明函数

sendMail( ): 这叫执行函数

ContractedBlock.gif

ExpandedBlockStart.gif

1 defsendMail():2

3 importsmtplib4 from email.mime.text importMIMEText5 from email.utils importformataddr6

7 msg = MIMEText("Python Email testing",'plain','utf-8')8 msg['From'] = formataddr(["Janice", "janicecheng.python@gmail.com"])9 msg['To'] = formataddr(["Janice", "janicecheng.python@gmail.com"])10 msg['Subject']='主題'

11

12 server = smtplib.SMTP("smtp.gmail.com", 587)13 server.starttls()14 server.login("janicecheng.python@gmail.com","password")15 server.sendmail("janicecheng.python@gmail.com",["janicecheng.python@gmail.com",], msg.as_string())16

17 print("Mail Send Successfully")18 server.quit()19

20 sendMail()

sendMail函数

1005794-20160828170020324-1922300173.png

注意:

当你在声明变量和函数之后,函数体在声明的时倏不会被执行的,它们分别会放在内存里,等待被调用!

在函数中一旦执行了 return, 函数的执行过程立即终止

返回值的补充说明

下面有一个例子,如果两个函数有相同的名称,然后在同一个程序里执行,运行结果会是多少呢?

1005794-20160828224835060-142492291.png

以下是程序运行時的顺序:

第一步:Python 运行程序的时候是从上而下执行的,在 f1 声明函数放在内存的时候,它把1+2 声明后,然后放在内存里

第二步:当程序运行时碰到第2个 f1函数时,它再次在内存中把1x 2 放在内存中,并且 f1 指向 (1 x 2)

Python 有自己的垃圾回收机制,会定时把没有的变量或者函数删除掉。

第三步:声明一个变量把f1函数的返回值存储在里面

第四步:当调用 f1函数时,它实际上是运行 a1 * a2

第五步:然后实际运行 f1函数

第六步:打印出 ret 变量中的值

所以调用 f1函数时,它其实正在运行 a1 * a2的功能,这就是为什么答案会是 64的原因。

参数的深入介绍和操作实战

把参数传入然后在函数体里的内码块可以把这个参数当成变量的去使用,这种参数叫形式参数。当我们在调用程序的时候把参数传入然后执行,这种参数叫实际参数。在這個例子中,参数 target_email 叫形式参数;下面执行程序传入的 “Alex” 叫实际参数。

1005794-20160828171153904-1656345010.png

如果从内存的角度去看这两种参数的话,在调用sendmail( ) 然后传入“alex” 的时候,这个“alex” 的字符串就已经在内存中,这就相当于把“xxoo” 这个形式参数指向内存中的实际参数“alex”; 同样地;对于“eric” 这个实际参数,它在被调用的时候,”eric” 已经在内存中等待着,然后函数本身的形式参数就会指向“ eric ”,然后执行程序,这就是形式参数和实际参数的关系。

1005794-20160828173211443-2067824454.png

还有就是形式参数和实际参数的位置默认情况下是一一对应的

1005794-20160828173300962-1980766166.png

在Python中也可以定义默认参数,意思是在声明函数的时候,其中一些形式参数已经定义了一些默认值,注意:如果想要定义默认参数,必需把默认参数放在参数列表的最后位置! ! !

ContractedBlock.gif

ExpandedBlockStart.gif

1 #content="This is a testing email" 是默认参数

2 def send(receipent,content="This is a testing email"):3 print("Email send to:",receipent,", Content:",content)4 print("Mail sent successfully")5 returnTrue6

7 send("janice@abc-company.com") #默认 content 用了 "This is a testing email"

8 send("janice@abc-company.com", "Company Notice") #content 用了 "Company Notice"

9

10 #Results:

11 #Email send to: janice@abc-company.com , Content: This is a testing email

12 #Mail sent successfully

13 #Email send to: janice@abc-company.com , Content: Company Notice

14 #Mail sent successfully

默认参数

也可以声明指定参数,在调用的时候输入 “”形式参数=实际参数” e.g. content=“alex",这样就可以在函数被調用時忽略参数顺序。

1005794-20160828173800670-74554615.png

对于动态参数有两种类: * 和 ** (分别是一个星号和两个星号)

* 一个星号: 默认将传入的参数,全部放在一个元组中。 f1(*[11,22,33,44])

** 两个星号: 默认将传入的参数,全部放在一个字典中。 f1(**{"k1":"v1","k2":"v2”})

动态参数 (*)会返回一个元组,如果函数的形式参数有* 号就有特殊的功能 e.g. def f1(*args),就是按照顺序接受传入什么的值都会转换到元组里面,并且当做元组的一个元素;如果在传实际参数的时候加一個星 * 号 e.g. f1(*li),它的特殊的功能是将这个列表里的每一个元素都转化到元组的元素里,其实就相当于在内部​​做了一个 For 循环,把列表里的一个一个添加到元组里(Tuple)。

ContractedBlock.gif

ExpandedBlockStart.gif

1 def f3(*args):2 print(args) #返回一個元組

3

4 li = [11,22,"Janice","dfghjk"]5 name = "Janice"

6

7 f3(li)8 f3(*li)9 f3(*"Janice")10 f3(*name)11

12 #Results:

13 #([11, 22, 'Janice', 'dfghjk'],)

14 #(11, 22, 'Janice', 'dfghjk')

15 #('J', 'a', 'n', 'i', 'c', 'e')

16 #('J', 'a', 'n', 'i', 'c', 'e')

动态参数*

动态参数 (**)会返回一個字典,如果函数的形式参数有** 号就有特殊的功能 e.g. def f1(**args),就是传入什么的值都会转换到字典里面,并且当做字典的value;如果在传实际参数的时候加上两个星** 号e.g. f1(**dic),它的特殊的功能是将这个字典里的每一个key, value 都给转化成字典的key, value,其实就相当于直接赋值到字典里。

ContractedBlock.gif

ExpandedBlockStart.gif

1 def f4(**args):2 print(args) #返回一個字典

3

4 li = [11,22,"Janice","dfghjk"]5 name = "Janice"

6

7 f4(n1="Janice")8 f4(n1="Janice", n2=20)9

10 dic = {"k1":"v1","k2":"v2"}11 f4(kk =dic)12 f4(**dic)13

14 #Results

15 #{'n1': 'Janice'}

16 #{'n1': 'Janice', 'n2': 20}

17 #{'kk': {'k1': 'v1', 'k2': 'v2'}}

18 #{'k1': 'v1', 'k2': 'v2'}

动态参数**

万能参数,def f5(*args, **kwargs) (注意:* 一个星号必须在前面, ** 两个星号必须在后面!)

ContractedBlock.gif

ExpandedBlockStart.gif

1 def f5(*args, **kwargs):2 print(args)3 print(kwargs)4

5 f5(11,22,33,44,k1="v1",k2="v2")6

7 #Results:

8 #(11, 22, 33, 44)

9 #{'k2': 'v2', 'k1': 'v1'}

万能参数*args, **kwargs

全局变量和局部变量

没有写到函数体里的变量叫全局变量,它在所有文件中都是可读;在f1函数里写的变量是 f1函数私有的,叫局部变量;变量会先找自己的局部变量,然后才找全局变量,如果你想修改全局变量(重新赋值),这时需要加入一个global 的关键字+ 它的变量名。如果以后要读一个全局变量的时候,直接打印 e.g. print() 一下就可以啦!

重点一、[列表, 字典, 元组] 如果在函数体里进行修改/新增, 这是在修改全区列表,但列表不容许在函数体里重新赋值。

重点二、如果是全局变量,命名时都需要大写! ! !

补充:函数的参数在传入的时候,到底是传入引用还是再传入一份列表,現在来分析一下两种结果:

如果传入的是一份列表,Python 在传入参数的时候是重新赋值的话,打印的时候就不应该出现 999

1005794-20160828181250442-1543034148.png

如果传入的是一个引用, li 和 a1 便会指向同一个列表

1005794-20160828181310537-1110144009.png

從运行后的结果可以总结:Python 在传参数的时候,其实是传入一个引用! ! !

ContractedBlock.gif

ExpandedBlockStart.gif

1 deff7(a1):2 a1.append(9999)3

4 li = [11,22,33,44]5 f7(li)6 print(li)7

8 #Results:

9 #[11, 22, 33, 44, 9999]

运行后结果

实战操作

运用函数写一个简单的猜文字游戏

1005794-20170405195458847-1895663303.png

ContractedBlock.gif

ExpandedBlockStart.gif

#!/usr/bin/env python#-*- coding: utf-8 -*-#Author: Janice Cheng

importosimportrandomimportsys#make a list of words

words =['apple','banana','orange','coconuts','straweberry','lime','graphefruit','lemon','kumquat','blueberry','melon']defclear():if os.name == 'nt':

os.system('cls')else:

os.system("clear")defdraw(bad_guess, good_guess, secret_word):

clear()print("Strikes: {}/7".format(bad_guess))print('')for letter inbad_guess:print(letter, end=' ')print('\n\n')for letter insecret_word:if letter ingood_guess:print(letter, end='')else:print('_', end='')print('')defget_guess(bad_guess, good_guess):whileTrue:

guess= input("Guess a letter:").lower()if len(guess) != 1:print("You can only guess a single letter!")elif guess in bad_guess or guess ingood_guess:print("You've already guess that letter")elif notguess.isalpha():print("You can only guess letters!")else:returnguessdefplay(done):

clear()

secret_word=random.choice(words)

bad_guess=[]

good_guess=[]whileTrue:

draw(bad_guess,good_guess,secret_word)

guess=get_guess(bad_guess,good_guess)if guess insecret_word:

good_guess.append(guess)

found=Truefor letter insecret_word:if letter not ingood_guess:

found=Falseiffound:print("You win!")print("The word was {}".format(secret_word))

done=Trueelse:

bad_guess.append(guess)if len(bad_guess) == 7:

draw(bad_guess,good_guess, secret_word)print("You lost!")print("The word was {}".format(secret_word))

done=Trueifdone:

play_again= input("Play again? y/n").lower()if play_again != 'n':return play(done=False)else:

sys.exit()defwelcome():print("Welcome to Letter Guess!!")

start= input("Press enter/return to start or Q to quit >>").lower()if start == 'q':print('Bye!')

sys.exit()else:returnTrueif __name__ == "__main__":

done=FalsewhileTrue:

clear()

welcome()

play(done)

猜文字游戏

format 函数操作实战

ret = '{0} lives in Hong Kong for more than {1} years!!'.format('Janice',20)

ret = '{name} lives in Hong Kong for more than {year} years!!'.format(name='Janice', year=20)

# Janice lives in Hong Kong for more than 20 years!!

这是 Python format 函数的源码,它也是接受一个 *号的参数和 ** 两个星号的参数

def format(self, *args, **kwargs): # known special case of str.format

"""

S.format(*args, **kwargs) -> str

Return a formatted version of S, using substitutions from args and kwargs.

The substitutions are identified by braces ('{' and '}').

"""

pass

一个 *星号的函数例子

ContractedBlock.gif

ExpandedBlockStart.gif

>>> s = "My name is {} and I am {} years old".format("Janice",20)>>>s'My name is Janice and I am 20 years old'

#在参数里加入*便可以接受列表类型

>>> s = "My name is {} and I am {} years old".format(*["Janice",20])>>>s'My name is Janice and I am 20 years old'

#这里不受列表类型

>>> s = "My name is {} and I am {} years old".format(["Janice",20])

Traceback (most recent call last):

File"", line 1, in IndexError: tuple index out of range#在括号里定义{0}和{1},就不需要在format()函数里重覆定义传递的内容

>>> s = "My name is {0} and {0} and {0} I am {1} years old".format("Janice",20)>>>s'My name is Janice and Janice and Janice I am 20 years old'

>>> s = "My name is {} and {} and {} I am {} years old".format("Janice",21)

Traceback (most recent call last):

File"", line 1, in IndexError: tuple index out of range

一个*星号的函数

两个** 星号的函数例子

ContractedBlock.gif

ExpandedBlockStart.gif

1 >>> s = "My name is {name} and I am {age} years old".format(name="Janice",age=20)2 >>>s3

4 >>> s = "My name is {name} and I am {age} years old".format(**{"name":"Janice","age":20}) #在参数里加入**便可以接受字典类型

5 >>>s6 'My name is Janice and I am 20 years old'

两个**星号的函数

实战操作

运用函数式编程来进行登录或注册实战

[更新中...]

lambda 表达式介绍

这是一个简单的函数: f1(a) = a + 100

ContractedBlock.gif

ExpandedBlockStart.gif

>>> deff1(a):

...return a + 100...>>> ret = f1(10)>>> print(ret)110

普通函数

lambda a: a + 100

# a + 100 是函数体,a 是变量,整句意思是输入参数 a,然后对a进行操作:a + 100

就以上的代码,可以用 lambda 表达式来实现

ContractedBlock.gif

ExpandedBlockStart.gif

>>> f2 = lambda a: a + 100 #自动返回

>>> ret2 = f2(10)>>> print(ret2)100

lambda 表达式例子一

ContractedBlock.gif

ExpandedBlockStart.gif

>>> add = lambda a1,a2: a1 + a2 #可以传两个参数

>>> add(10,10)20

lambda 表达式例子二

lambda 中的 filter 例子

ContractedBlock.gif

ExpandedBlockStart.gif

>>> lst = [11,22,33,44]#Option1

>>> deff(x):

...return x > 22

>>>list(filter(f, lst))

[33, 44]#Option2

>>> list(filter(lambda a: a > 22, lst))

[33, 44]

lambda 表达式例子三

lambda 中的 map 例子

ContractedBlock.gif

ExpandedBlockStart.gif

>>> lst1 = [1,3,5,6,9]>>> lst2 = [2,4,6,8,10]>>> ret = map(lambda x,y: x+y, lst1, lst2)>>>list(ret)

[3, 7, 11, 14, 19]

lambda 表达式例子四

大家都应该听过 Spark,在 Spark 里用了很多 lambda 表达式来实现 filter、map、flatMap 和 reduceByKey 的功能,以下是一個 Spark 的 wordcount 例子

wordCounts = textFile.flatMap(lambda line: line.split())\

.map(lambda word: (word, 1))\

.reduceByKey(lambda a, b: a+b)

文件操作函数介紹和操作实战

打開文件

##Operation

output = open(r'C:\spam', 'w') #Create output file ('w' means write)

input = open('data', 'r') #Create input file ('r' means read)

input = open('data') #Same as prior line ('r' is the default)

open('f.txt', encoding='latin-1') #Python 3.X Unicode text files (str strings)

open('f.bin', 'rb') #Python 3.X bytes files (bytes strings)

open('f.bin', 'rb') #Python 2.X bytes files (str strings)

for line in open('data'): #File iterators read line by line

操作文件

##Method

aString = input.read() #Read entire file into a single string

aString = input.read(N) #Read up to nextNcharacters (or bytes) into a string

aString = input.readline() #Read next line (including\nnewline) into a string

aList = input.readlines() #Read entire file into list of line strings (with \n)

output.write(aString) #Write a string of characters (or bytes) into file

output.writelines(aList) #Write all line strings in a list into file

output.close() #Manual close (done for you when file is collected)

output.flush() #Flush output buffer to disk without closing

anyFile.seek(N) #Change file position to offsetNfor next operation

文件的打开方式不同就会对文件产生不同的影响,打开方式有几种:1)以字符串类型读写文件; 2) 有加号的方式读写文件; 3) 以二进制(字节)类型读写文件;

1005794-20160906213800254-1948699260.png

ContractedBlock.gif

ExpandedBlockStart.gif

#Remember to close the file after every file modification

f = open("readme.txt",'w') #open a file for writing

f.write("this is the first line\n") #write a line to the file

f.write("this is the second line\n") #write one more line to the file

f.close() #close a file

f= open("readme.txt",'r') #open a file for reading

f.read() #read the entire content of file at once

f.read(1) #read 1 char from the file

f.seek(1) #调整指针到第一个位置

f.tell()

f.readable()#是否是可读文件

f.readlines() #reading all lines as an array

f.readlines() #read only one line

f.close() #close a file

f= open("readme.txt",'a') #append data to the original file

f.write("this is the third line\n") #write a line to the file

f.close() #close a file

文件操作

以字符串类型打开:

Append: "a" - 以追加的方式打开文件,(打开文件后的文件指针会自动移到文件末尾) 如果文件不存在则创建。

ContractedBlock.gif

ExpandedBlockStart.gif

f = open("db","a")

f.write("Python")

f.close()#Before: admin|123#After: admin|123Python

Append:a

Read: "r" - 以读的方式打开文件,可读取文件信息。

ContractedBlock.gif

ExpandedBlockStart.gif

1 >>> f2 = open("db","r")2 >>> data2 =f2.read()3 >>> print(data2)4 Admin|123

5 Alex|alex34176 >>> print(type(data2))7

Read:r

Write: "w" - 以写的方式打开文件,如果文件存在,则清空该文件,再重新写入新内容。

ContractedBlock.gif

ExpandedBlockStart.gif

1 >>> importcsv2 >>> f2 = open("db","w")3 >>> data = "admin|123"

4 >>>f2.write(data)5 9

6 >>> f2.close()

Write:w

Extend: "x" - 如果这个文件存在就报错,如果不存在就创建并写内容 (跟 w 是一样的,只增加多一个条件判断,判断一下当前文件是否已经存在)

ContractedBlock.gif

ExpandedBlockStart.gif

1 >>> f2 = open("db","x") #如果文件已经存在,你会报错

2 Traceback (most recent call last):3 File "", line 1, in

4 FileExistsError: [Errno 17] File exists: 'db'

5

6 >>> f2 = open("db_test","x")7 >>> data = "admin|123"

8 >>>f2.write(data)9 9

10 >>> f2.close()

Extend:x

有+號的打開模式

Append: "a+" - 以读写方式打开文件,并把文件指针移到文件尾。

Read: "r+" - 以读写方式打开文件,可以对文件进行读写操作,Python 在读完整个文件的时候,默认指针位置会在文件的末位​​,所以当 f.write("9999") 的时候,就会在文件最后的位置追加,所以如果用 "r" 打开时,可以配合 seek() 来指定写入的位置 (看下面seek()的例子)。

ContractedBlock.gif

ExpandedBlockStart.gif

1 >>> f = open("db","r+", encoding='utf-8')2 >>> data =f.read()3 >>> print(data)4 admin|123

5 >>> f.write("9999")6 11

7 >>>f.close()8

9 #Results:

10 #Before: admin|123

11 #After: admin|1239999

Read:r+

Write: "w+" -清除文件内容、然后以读写方式打开文件。可读可写,但會先清空,後再寫。

以二进制(字节)类型打开

Append: "ab" - 如果使用二进制的方式写,必需也得传入字节类型

ContractedBlock.gif

ExpandedBlockStart.gif

1 >>> f = open("db","ab")2 >>> f.write(bytes("Python", encoding='utf-8'))3 6

4 >>>f.close()5

6 #Results:

7 #Before: admin|123

8 #After: admin|123Python

Append:ab

如果使用二进制的方式去写数据,但传入的是一个字符串,这时候程序就会报错!

ContractedBlock.gif

ExpandedBlockStart.gif

1 >>> f3 = open("db","ab") #如果加b只能写入字节

2 >>> f3.write("hello")3 Traceback (most recent call last):4 File "", line 1, in

5 TypeError: a bytes-like object is required, not 'str'

Append:ab

Read: "rb" - 只读,在读文件时自己去跟Python 底层的二进制沟通,你读的时候是读二进制,所以写的时候也需要写上二进制(字节),在硬盘上存储的是二进制格式,Python 在读的时候,默认把底层的二进制字节转转换成字符串,所以打印出来才会是字符串。

ContractedBlock.gif

ExpandedBlockStart.gif

1 >>> f1 = open("db","rb")2 >>> data1 =f1.read()3 >>> print(data1)4 b'Admin|123\nAlex|alex3417'

5 >>> print(type(data1))6

Read:rb

**注意: encoding 这个参数,它是 Python 在把字节转化成字符串设定的一个编码,Python 会按照这个编码帮我们转换。意思就是说你用什么编码去存储文件(写)的同时,也应该用相同的编码去打开(读)文件。如果把 b 取掉读到的就是字符串类型,所以如果在打开文件的时候出现乱码,很大可能是这个 encoding 出现问题。

f=open("db","r",encoding="GBK")

Write: "wb"

文件操作的功能

seek( ): 主动调整指针的位置,指针跳到指定位置 (永远以字符的方式找位置)

ContractedBlock.gif

ExpandedBlockStart.gif

1 >>> f = open("db","r+")2 >>> data = f.read(1)3 >>> print(data)4 a5 >>> f.seek(1) #调整指针到第一个位置

6 1

7 >>> f.write("999") #当前指针位置开始向后覆盖,写数据,打开方式有 b 、只能写字节;无b就是写字符

8 3

9 >>>f.close()10

11 #Results:

12 #Before: #admin|123

13 #After: #a999n|123

seek()

tell( ): 获取当前指针的位置(字节),因為一個中文是3個字節,所以當調用read(1)方法之後,再查看當前字節位置,就會返回3

ContractedBlock.gif

ExpandedBlockStart.gif

1 >>> f = open("db","r+")2 >>> data = f.read(1)3 >>> print(data)4 金5 >>> print(f.tell())6 3

7

8 #db: 金|123

tell()

read( ): 默认无参数,读全部,如果在打开文件的时候是"rb",读取的时候会按字节;如果在打开文件的时候是"r",读取的时候会按字符。

ContractedBlock.gif

ExpandedBlockStart.gif

1 >>> f = open("db","rb")2 >>> data = f.read(1)3 >>> print(data)4 b'\xe9'

5 >>>f.close()6 >>> f = open("db","r+")7 >>> data = f.read(1)8 >>> print(data)9 金10 >>> f.close()

read()

write( ): 写数据,如果在打开文件的时候是"rb",读取的时候会按字节;如果在打开文件的时候是"r",读取的时候会按字符。

close( ):

fileno( ):

flush( ): 刷新,在文件还没有close()之前,f.write 的数据会存放在内存里而不直接写入文件,如果用了flush()的话,它就会在文件还没有调用close()的状况下强行把数据写入文件中。

ContractedBlock.gif

ExpandedBlockStart.gif

1 >>> f = open("db","a")2 >>> f.write("888")3 3

4 >>>

5 >>> input("Please input a number:") #等待着用户输入

6 Please input a number:

flush()

readable( ): 判断是否可读

ContractedBlock.gif

ExpandedBlockStart.gif

1 >>> f2 = open("db_test","w")2 >>>f2.readable()3 False4 >>> f1 = open("db_test","r")5 >>>f1.readable()6 True

readable()

seekable( ):

readline( ): 只读取一行(读取的过程指针会在移动)

ContractedBlock.gif

ExpandedBlockStart.gif

1 db.txt2 admin|123

3 janice|janice1234 alex|alex1235 kennith|ken1236

7 >>> f1 = open("db","r")8 >>>f1.readline()9 'admin|123\n'

10 >>>f1.readline()11 'janice|janice123\n'

12 >>> f1.close()

readline()

truncate( ):截断数据,只把指针位置后的清空

ContractedBlock.gif

ExpandedBlockStart.gif

1 f = open("db","r+",encoding='utf-8')2 f.seek(3)3 f.truncate()4 f.close()5

6 #admin|123

7 #adm

truncate()

for-loop:

ContractedBlock.gif

ExpandedBlockStart.gif

1 f = open("db","r+",encoding='utf-8')2 for line inf:3 print(line)4

5

6 f.close()7

8 #admin|123

9 #alex|alex3417

10 #kennith|ken3344

for-loop

關閉文件

close( )

f = close()

with 文件操作

ContractedBlock.gif

ExpandedBlockStart.gif

1 with open("db","r+", encoding='utf-8') as f:2 for line inf:3 print(line)4

5 #admin|123

6 #alex|alex3417

7 #kennith|ken3344

with f1

with 同時操作兩個文件

ContractedBlock.gif

ExpandedBlockStart.gif

1 #從db1文件一个以只读的方法打开,從db2文件一个以只写的方法打开

2 #从DB1读一行写一行到DB2

3 with open("db1","r", encoding='utf-8') as f1, open("db2","w", encoding='utf-8') as f2:4 for line inf1:5 new_line = line.replace("alex","eric")6 f2.write(new_line)

with f1, f2

gzip

ContractedBlock.gif

ExpandedBlockStart.gif

>>> importgzip>>> with gzip.open('score.csv.gz','rt') as f:

...print(f.read())

...

chinese,88english,90maths,85computer science,90chemistry,67music,88economics,75

gzip

本周作业

操作 haproxy.conf 文件

ContractedBlock.gif

ExpandedBlockStart.gif

1 global

2 log 127.0.0.1local23 daemon4 maxconn 256

5 log 127.0.0.1local2 info6 defaults7 log global

8 mode http9 timeout connect 5000ms10 timeout client 50000ms11 timeout server 50000ms12 option dontlognull13 listen stats :8888

14 stats enable15 stats uri /admin16 stats auth admin:1234

17 frontend oldboy.org18 bind 0.0.0.0:80

19 option httplog20 option httpclose21 option forwardfor22 log global

23 acl www hdr_reg(host) -i www.oldboy.org24 use_backend www.oldboy.org ifwww25 backend www.oldboy.org26 server 100.1.7.9 100.1.7.9 weight 20 maxconn 3000

27 backend buy.oldboy.org28 server 100.1.7.90 100.1.7.90 weight 20 maxconn 3000

haproxy.cof

参考资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值