python学习-day14:集合,函数,格式化
一、集合
定义:由不同元素组成的集合。集合是一组无序排列的可hash值, 可以作为字典的key。元素必须是不可变类型:只能存放数字,字符串,字典
特性:集合的目的是将不同的值放在一起,不同的集合之间可以用来做关系运算,无序纠结于集合中的单个值。
2.1、集合的创建
- class set(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. A中存在,B中不存在
- (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. 从当前集合中删除和B中相同的元素"""
- 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. 取交集并更更新到A中 """
- pass
- def isdisjoint(self, *args, **kwargs): # real signature unknown
- """ Return True if two sets have a null intersection. 如果没有交集,返回True,否则返回False"""
- 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
- def 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. 对称差集,并更新到a中 """
- 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
set函数
①s={1,2,3,1}
②set函数来进行创建:把实参进行for循环,一个一个进行放置到新的列表中去。
- s=set(['alex','alex','sb'])
- print(s)
- set_test=set('hello')
- print(set_test)
- {'alex', 'sb'}
- {'e', 'l', 'o', 'h'}
2.1集合内置方法:
①、add(self, *args, **kwargs),添加元素。
- s={1,2,3,4,5,6}
- s.add('s')
- print(s)
- s.add('') #可以加入字符串:'3'
- print(s)
- s.add(3)
- print(s)
- >>>
- {'s', 1, 2, 3, 4, 5, 6}
- {'s', 1, 2, 3, 4, 5, 6, ''}
- {'s', 1, 2, 3, 4, 5, 6, ''}
②、clear(self, *args, **kwargs)。清空集合
- s={1,2,3,4,5,6}
- s.clear()
- print(s)
- >>>
- set()
③、copy(self, *args, **kwargs)。复制
- s={'sb',1,2,3,4,5,6}
- s1=s.copy()
- print(s1)
- >>>
- {1, 2, 3, 4, 5, 6, 'sb'}
④、s.pop() 随机删除
- s={'sb',1,2,3,4,5,6}
- s1=s.pop()
- print(s1)
- print(s)
- >>>
- 1
- {2, 3, 4, 5, 6, 'sb'}
⑤、指定删除:
s.remove(self, *args, **kwargs) #删除元素不存在会报错
discard(self, *args, **kwargs) #删除元素不存在不会报错
- s={'sb',1,2,3,4,5,6}
- s.remove('sb')
- print(s)
- s.remove('hellol')
- print(s)
- s.discard('sbbbb')
- print(s)
- >>>
- {1, 2, 3, 4, 5, 6}
- 报错
- 没有移除元素,打印原集合。
⑥、intersection(self, *args, **kwargs) 求两个元素的交集。相当于s1&s2
intersection.update 求交集后把结果赋值给P_S
- python_1=['lcg','zsw','zjw']
- linux_1=['lcg','szw']
- p_s=set(python_1)
- l_s=set(linux_1)
- print(p_s,l_s)
- t=l_s.intersection(p_s)
- print(t)
- >>>>
- {'lcg', 'zsw', 'zjw'} {'lcg', 'szw'}
- {'lcg'}
⑦、union 求并集 a|b
- python_1=['lcg','zsw','zjw']
- linux_1=['lcg','szw']
- p_s=set(python_1)
- l_s=set(linux_1)
- print(p_s.union(l_s))
- >>>>
- {'szw', 'lcg', 'zsw', 'zjw'}
⑧、1、difference(self, *args, **kwargs) 求差集 p_s-l_s
2、difference.update 求差集后把结果赋值给P_s
- python_1=['lcg','zsw','zjw']
- linux_1=['lcg','szw']
- p_s=set(python_1)
- l_s=set(linux_1)
- print(p_s-l_s)
- >>>
- {'zjw', 'zsw'}
⑨、symmetric_difference、交叉补集 符号表达式: p_s^l_s
- python_1=['lcg','szw','zjw']
- linux_1=['lcg','szw','sb']
- p_s=set(python_1)
- l_s=set(linux_1)
- print(p_s.symmetric_difference(l_s))
- >>>
- {'zjw', 'sb'}
10、isdisjoint(self, *args, **kwargs) 判断是否没有交集。没有交集-True。
- python_1=['lcg','szw','zjw']
- linux_1=['lcg','szw','sb']
- p_s=set(python_1)
- l_s=set(linux_1)
- print(p_s.isdisjoint(l_s))
- >>>
- False
11、issubset→是否是子集
issuperset→是否是父集
- python_1=['lcg','szw','zjw']
- linux_1=['lcg','szw',]
- p_s=set(python_1)
- l_s=set(linux_1)
- print(p_s.issubset(l_s))
- python_1=['lcg','szw','zjw']
- linux_1=['lcg','szw',]
- p_s=set(python_1)
- l_s=set(linux_1)
- print(l_s.issubset(p_s))
- >>>
- False
- True
12、update 更新增加多个值 s1.update(s2) s2可以是集合、元祖,列表:可迭代的都可以传入。 add只能更新增加一个值。
- python_1=['lcg','szw','zjw']
- linux_1=['lcg','szw','as']
- p_s=set(python_1)
- l_s=set(linux_1)
- p_s.update(l_s)
- print(p_s)
- >>>>
- {'as', 'lcg', 'zjw', 'szw'}
深浅拷贝
一、数字和字符串
对于 数字 和 字符串 而言,赋值、浅拷贝和深拷贝无意义,因为其永远指向同一个内存地址。
import
copy
# ######### 数字、字符串 #########
n1
=
123
# n1 = "i am alex age 10"
print
(
id
(n1))
# ## 赋值 ##
n2
=
n1
print
(
id
(n2))
# ## 浅拷贝 ##
n2
=
copy.copy(n1)
print
(
id
(n2))
# ## 深拷贝 ##
n3
=
copy.deepcopy(n1)
print
(
id
(n3))

二、其他基本数据类型
对于字典、元祖、列表 而言,进行赋值、浅拷贝和深拷贝时,其内存地址的变化是不同的。
1、赋值
赋值,只是创建一个变量,该变量指向原来内存地址,如:
1
2
3
|
n1 = { "k1" : "wu" , "k2" : 123 , "k3" : [ "alex" , 456 ]} n2 = n1 |

2、浅拷贝
浅拷贝,在内存中只额外创建第一层数据
1
2
3
4
5
|
import copy n1 = { "k1" : "wu" , "k2" : 123 , "k3" : [ "alex" , 456 ]} n3 = copy.copy(n1) |

3、深拷贝
深拷贝,在内存中将所有的数据重新创建一份(排除最后一层,即:python内部对字符串和数字的优化)
1
2
3
4
5
|
import copy n1 = { "k1" : "wu" , "k2" : 123 , "k3" : [ "alex" , 456 ]} n4 = copy.deepcopy(n1) |

wusir
函数
一、背景
在学习函数之前,一直遵循:面向过程编程,即:根据业务逻辑从上到下实现功能,其往往用一长段代码来实现指定功能,开发过程中最常见的操作就是粘贴复制,也就是将之前实现的代码块复制到现需功能处,如下:
- while True:
- if cpu利用率 > 90%:
- #发送邮件提醒
- 连接邮箱服务器
- 发送邮件
- 关闭连接
- if 硬盘使用空间 > 90%:
- #发送邮件提醒
- 连接邮箱服务器
- 发送邮件
- 关闭连接
- if 内存占用 > 80%:
- #发送邮件提醒
- 连接邮箱服务器
- 发送邮件
- 关闭连接
- def 发送邮件(内容)
- #发送邮件提醒
- 连接邮箱服务器
- 发送邮件
- 关闭连接
- while True:
- if cpu利用率 > 90%:
- 发送邮件('CPU报警')
- if 硬盘使用空间 > 90%:
- 发送邮件('硬盘报警')
- if 内存占用 > 80%:
对于上述的两种实现方式,第二次必然比第一次的重用性和可读性要好,其实这就是函数式编程和面向过程编程的区别:
- 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可
- 面向对象:对函数进行分类和封装,让开发“更快更好更强...”
函数式编程最重要的是增强代码的重用性和可读性
二、定义和使用
def
函数名(参数):
...
函数体
...
返回值
函数的定义主要有如下要点:
- def:表示函数的关键字
- 函数名:函数的名称,日后根据函数名调用函数
- 函数体:函数中进行一系列的逻辑计算,如:发送邮件、计算出 [11,22,38,888,2]中的最大数等...
- 参数:为函数体提供数据
- 返回值:当函数执行完毕后,可以给调用者返回数据。
1、返回值
函数是一个功能块,该功能到底执行成功与否,需要通过返回值来告知调用者。
以上要点中,比较重要有参数和返回值:
- def 发送短信():
- 发送短信的代码...
- if 发送成功:
- return True
- else:
- return False
- while True:
- # 每次执行发送短信函数,都会将返回值自动赋值给result
- # 之后,可以根据result来写日志,或重发等操作
- result = 发送短信()
- if result == False:
- 记录日志,短信发送失败...
2、参数
为什么要有参数?
- def CPU报警邮件()
- #发送邮件提醒
- 连接邮箱服务器
- 发送邮件
- 关闭连接
- def 硬盘报警邮件()
- #发送邮件提醒
- 连接邮箱服务器
- 发送邮件
- 关闭连接
- def 内存报警邮件()
- #发送邮件提醒
- 连接邮箱服务器
- 发送邮件
- 关闭连接
- while True:
- if cpu利用率 > 90%:
- CPU报警邮件()
- if 硬盘使用空间 > 90%:
- 硬盘报警邮件()
- if 内存占用 > 80%:
- 内存报警邮件()
无参数实现
- def 发送邮件(邮件内容)
- #发送邮件提醒
- 连接邮箱服务器
- 发送邮件
- 关闭连接
- while True:
- if cpu利用率 > 90%:
- 发送邮件("CPU报警了。")
- if 硬盘使用空间 > 90%:
- 发送邮件("硬盘报警了。")
- if 内存占用 > 80%:
- 发送邮件("内存报警了。")
有参数实现
函数的有三中不同的参数:
- 普通参数
- 默认参数
- 动态参数
- # ######### 定义函数 #########
- # name 叫做函数func的形式参数,简称:形参
- def func(name):
- print name
- # ######### 执行函数 #########
- # 'wupeiqi' 叫做函数func的实际参数,简称:实参
- func('wupeiqi')
普通参数
- def func(name, age = 18):
- print "%s:%s" %(name,age)
- # 指定参数
- func('wupeiqi', 19)
- # 使用默认参数
- func('alex')
- 注:默认参数需要放在参数列表最后
默认参数
- def func(*args):
- print args
- # 执行方式一
- func(11,33,4,4454,5)
- # 执行方式二
- li = [11,2,2,3,3,4,54]
- func(*li)
动态参数
- def func(**kwargs):
- print args
- # 执行方式一
- func(name='wupeiqi',age=18)
- # 执行方式二
- li = {'name':'wupeiqi', age:18, 'gender':'male'}
- func(**li)
动态参数
- def func(*args, **kwargs):
- print args
- print kwargs
动态参数
扩展:发送邮件实例
- import smtplib
- from email.mime.text import MIMEText
- from email.utils import formataddr
- msg = MIMEText('邮件内容', 'plain', 'utf-8')
- msg['From'] = formataddr(["武沛齐",'wptawy@126.com'])
- msg['To'] = formataddr(["走人",'424662508@qq.com'])
- msg['Subject'] = "主题"
- server = smtplib.SMTP("smtp.126.com", 25)
- server.login("wptawy@126.com", "邮箱密码")
- server.sendmail('wptawy@126.com', ['424662508@qq.com',], msg.as_string())
- server.quit()
发送邮件实例
内置函数
注:查看详细猛击这里
open函数,该函数用于文件处理
操作文件时,一般需要经历如下步骤:
- 打开文件
- 操作文件
一、打开文件
1
|
文件句柄 = open ( '文件路径' , '模式' ) |
打开文件时,需要指定文件路径和以何等方式打开文件,打开后,即可获取该文件句柄,日后通过此文件句柄对该文件操作。
打开文件的模式有:
- r ,只读模式【默认】
- w,只写模式【不可读;不存在则创建;存在则清空内容;】
- x, 只写模式【不可读;不存在则创建,存在则报错】
- a, 追加模式【可读; 不存在则创建;存在则只追加内容;】
"+" 表示可以同时读写某个文件
- r+, 读写【可读,可写】
- w+,写读【可读,可写】
- x+ ,写读【可读,可写】
- a+, 写读【可读,可写】
"b"表示以字节的方式操作
- rb 或 r+b
- wb 或 w+b
- xb 或 w+b
- ab 或 a+b
注:以b方式打开时,读取到的内容是字节类型,写入时也需要提供字节类型
二、操作
- class TextIOWrapper(_TextIOBase):
- """
- Character and line based layer over a BufferedIOBase object, buffer.
- encoding gives the name of the encoding that the stream will be
- decoded or encoded with. It defaults to locale.getpreferredencoding(False).
- errors determines the strictness of encoding and decoding (see
- help(codecs.Codec) or the documentation for codecs.register) and
- defaults to "strict".
- newline controls how line endings are handled. It can be None, '',
- '\n', '\r', and '\r\n'. It works as follows:
- * On input, if newline is None, universal newlines mode is
- enabled. Lines in the input can end in '\n', '\r', or '\r\n', and
- these are translated into '\n' before being returned to the
- caller. If it is '', universal newline mode is enabled, but line
- endings are returned to the caller untranslated. If it has any of
- the other legal values, input lines are only terminated by the given
- string, and the line ending is returned to the caller untranslated.
- * On output, if newline is None, any '\n' characters written are
- translated to the system default line separator, os.linesep. If
- newline is '' or '\n', no translation takes place. If newline is any
- of the other legal values, any '\n' characters written are translated
- to the given string.
- If line_buffering is True, a call to flush is implied when a call to
- write contains a newline character.
- """
- def close(self, *args, **kwargs): # real signature unknown
- 关闭文件
- pass
- def fileno(self, *args, **kwargs): # real signature unknown
- 文件描述符
- pass
- def flush(self, *args, **kwargs): # real signature unknown
- 刷新文件内部缓冲区
- pass
- def isatty(self, *args, **kwargs): # real signature unknown
- 判断文件是否是同意tty设备
- pass
- def read(self, *args, **kwargs): # real signature unknown
- 读取指定字节数据
- pass
- def readable(self, *args, **kwargs): # real signature unknown
- 是否可读
- pass
- def readline(self, *args, **kwargs): # real signature unknown
- 仅读取一行数据
- pass
- def seek(self, *args, **kwargs): # real signature unknown
- 指定文件中指针位置
- pass
- def seekable(self, *args, **kwargs): # real signature unknown
- 指针是否可操作
- pass
- def tell(self, *args, **kwargs): # real signature unknown
- 获取指针位置
- pass
- def truncate(self, *args, **kwargs): # real signature unknown
- 截断数据,仅保留指定之前数据
- pass
- def writable(self, *args, **kwargs): # real signature unknown
- 是否可写
- pass
- def write(self, *args, **kwargs): # real signature unknown
- 写内容
- pass
- def __getstate__(self, *args, **kwargs): # real signature unknown
- pass
- def __init__(self, *args, **kwargs): # real signature unknown
- 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 __next__(self, *args, **kwargs): # real signature unknown
- """ Implement next(self). """
- pass
- def __repr__(self, *args, **kwargs): # real signature unknown
- """ Return repr(self). """
- pass
- buffer = property(lambda self: object(), lambda self, v: None, lambda self: None) # default
- closed = property(lambda self: object(), lambda self, v: None, lambda self: None) # default
- encoding = property(lambda self: object(), lambda self, v: None, lambda self: None) # default
- errors = property(lambda self: object(), lambda self, v: None, lambda self: None) # default
- line_buffering = property(lambda self: object(), lambda self, v: None, lambda self: None) # default
- name = property(lambda self: object(), lambda self, v: None, lambda self: None) # default
- newlines = property(lambda self: object(), lambda self, v: None, lambda self: None) # default
- _CHUNK_SIZE = property(lambda self: object(), lambda self, v: None, lambda self: None) # default
- _finalizing = property(lambda self: object(), lambda self, v: None, lambda self: None) # default
3.x
三、管理上下文
为了避免打开文件后忘记关闭,可以通过管理上下文,即:
1
2
3
|
with open ( 'log' , 'r' ) as f: ... |
如此方式,当with代码块执行完毕时,内部会自动关闭并释放文件资源。
在Python 2.7 及以后,with又支持同时对多个文件的上下文进行管理,即:
1
2
|
with open ( 'log1' ) as obj1, open ( 'log2' ) as obj2: pass |
三、管理上下文
为了避免打开文件后忘记关闭,可以通过管理上下文,即:
1
2
3
|
with open ( 'log' , 'r' ) as f: ... |
如此方式,当with代码块执行完毕时,内部会自动关闭并释放文件资源。
在Python 2.7 及以后,with又支持同时对多个文件的上下文进行管理,即:
1
2
|
with open ( 'log1' ) as obj1, open ( 'log2' ) as obj2: pass |
lambda表达式
学习条件运算时,对于简单的 if else 语句,可以使用三元运算来表示,即:
1
2
3
4
5
6
7
8
|
# 普通条件语句 if 1 = = 1 : name = 'wupeiqi' else : name = 'alex' # 三元运算 name = 'wupeiqi' if 1 = = 1 else 'alex' |
对于简单的函数,也存在一种简便的表示方式,即:lambda表达式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
# ###################### 普通函数 ###################### # 定义函数(普通方式) def func(arg): return arg + 1 # 执行函数 result = func( 123 ) # ###################### lambda ###################### # 定义函数(lambda表达式) my_lambda = lambda arg : arg + 1 # 执行函数 result = my_lambda( 123 ) |
递归
利用函数编写如下数列:
斐波那契数列指的是这样一个数列 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368...
1
2
3
4
5
6
7
8
|
def func(arg1,arg2): if arg1 = = 0 : print arg1, arg2 arg3 = arg1 + arg2 print arg3 func(arg2, arg3) func( 0 , 1 ) |
练习题
1、简述普通参数、指定参数、默认参数、动态参数的区别
2、写函数,计算传入字符串中【数字】、【字母】、【空格] 以及 【其他】的个数
3、写函数,判断用户传入的对象(字符串、列表、元组)长度是否大于5。
4、写函数,检查用户传入的对象(字符串、列表、元组)的每一个元素是否含有空内容。
5、写函数,检查传入列表的长度,如果大于2,那么仅保留前两个长度的内容,并将新内容返回给调用者。
6、写函数,检查获取传入列表或元组对象的所有奇数位索引对应的元素,并将其作为新列表返回给调用者。
7、写函数,检查传入字典的每一个value的长度,如果大于2,那么仅保留前两个长度的内容,并将新内容返回给调用者。
1
2
3
|
dic = { "k1" : "v1v1" , "k2" : [ 11 , 22 , 33 , 44 ]} PS:字典中的value只能是字符串或列表 |
8、写函数,利用递归获取斐波那契数列中的第 10 个数,并将该值返回给调用者。
二、函数
2.1、数学定义:
一般的,在一个变化过程中,如果有两个变量x和y,并且对于x的每一个确定的值,y都有唯一确定的值与其对应,那么我们就把x称为自变量,把y称为因变量,y是x的函数。自变量x的取值范围叫做这个函数的定义域。
python函数定义:
函数是逻辑结构化和过程化的一种编程方法。
- def 函数名(形参) #定义函数名称和参数结构
- 。。。。 # 函数中间,逻辑运算过程
- return @ #返回函数的运行结果值。运行过程中一碰到return就结束函数当前的调用函数。
- a=函数名(实参数) # 调用函数
没有return的话只有只是一个过程。
有return:就是一个完整的函数。
- def test():
- '''
- 2*x+1
- :param x:整形数字
- :return: 返回计算结果
- '''
- x=3
- y=2*x+1
- return y
- a=test() #定义变量a,接住函数返回的值
- print(a)
总结使用函数的好处:
1.代码重用
2.保持一致性,易维护
3.可扩展性
2.2、函数和过程
- def test01():
- msg = 'test01'
- print(msg)
- def test02():
- msg = 'test02'
- print(msg)
- return msg
- def test03():
- msg = 'test03'
- print(msg)
- return 1,2,3,4,'a',['alex'],{'name':'alex'},None
- def test04():
- msg = 'test03'
- print(msg)
- return {'name':'alex'}
- t1=test01()
- t2=test02()
- t3=test03()
- t4=test04()
- print(t1)
- print(t2)
- print(t3)
- print(t4)
- >>>>>
- test01
- test02
- test03
- test03
- None
- test02
- (1, 2, 3, 4, 'a', ['alex'], {'name': 'alex'}, None) 把字符串放在一个元祖里面。返回值>1
- {'name': 'alex'}
- def test05():
- msg='dskddDSD酸'
- print(msg)
- return {1,2,4,5}
- a=test05()
- print(a)
- >>>
- {1, 2, 4, 5}
过程定义:过程定义:过程就是简单特殊没有返回值的函数
总结:当一个函数/过程没有使用return显示的定义返回值时,python解释器会隐式的返回None,
所以在python中即便是过程也可以算作函数。
总结:
返回值数=0:返回None 无定义返回值
返回值数=1:返回object
返回值数>1:返回tuple
三、函数参数
1.形参变量:[形参变量,变量只是一个名字,代号,只有值,数据类型才会占用内存在没有赋值的情况下不占用内存空间。],
只有在被调用时才分配内存单元在调用结束时,即刻释放所分配的内存单元。因此,形参只在函数内部有效。函数调用结束返回主调用函数后,则不能再使用该形参变量
2.实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等办法使参数获得确定值
直接print(形参)会出现报错的情况,形参没有值!!!所以没法打印值
- 函数的形式:
- def calc(x,y): #定义形式参数-形参变量
- res=x**y
- return res
- c=calc(a,b) #实参数
- print(c)
3.位置参数和关键字(标准调用:实参与形参位置一一对应;关键字调用:位置无需固定)
3.1、位置参数
- def cala (x,y,z):
- print(x)
- print(y)
- print(z)
- a=cala(1,2) #位置参数要一一对应,不能多一个,也不能少一个!
3.2、关键字参数
- def cala (x,y,z):
- print(x)
- print(y)
- print(z)
- a=cala(x=1,y=2,z=3) #关键字参数,无位置顺序要求。按照关键字进行一一对应。也是缺一不可!
- print(a)
- >>>
- 1
- 2
- 3
- None
3.3、混搭:位置参数和关键字参数混合使用
- def cala (x,y,z):
- print(x)
- print(y)
- print(z)
- # test(1,y=2,3)#报错
- # test(1,3,y=2)#报错
- # test(1,3,z=2,y=4)#报错
- # test(z=2,1,3)#报错
- a=cala(1,y=2,z=3) #可以把两者混搭,可是必须遵从。位置参数必须在关键字参数左边。
#a=cala(1,2,y=3) 2先赋值给y,之后在替换赋值3,缺少Z的参数赋值,所以仍然会报错- print(a)
3.4、关键字参数不允许多个值,不存在后来值覆盖前面值的说法!
- def cala(x,y,z):
- up=x+y+z
- return up
- a=cala(1,2,y=2)
- print(a)
- #got multiple values for argument 'y'
- 有多个参数的值“Y”
3.4、函数返回值:没有返回值,相当于函数是一个执行过程,仍然会执行函数内部的程序。只是函数的执行个结果为:None
- def test01():
- msg="dsadsdad"
- print(msg) #没有return,运行该函数没有返回值。接着函数的结果是:None
- a=test01()
- print(a)
- def test02():
- msg='dsdsds'
- print(msg)
- return msg #return为函数内部的关键字
- a=test02()
- print(a)
- def test03():
- msg='dsds'
- return 1,2,3,'dddfdfd',{'dsds':'dsd'},['dsds','dsd'] #3可以返回字符串函数。会把字符串放置在一个元祖内部
- a=test03()
- print(a)
- def test04():
- msg='sdsds'
- return test03 #可以返回函数的内存地址,
- a=test04()() #加上内存地址+() 等于运行该程序
- print(a)
- dsadsdad
- None
- dsdsds
- dsdsds
- (1, 2, 3, 'dddfdfd', {'dsds': 'dsd'}, ['dsds', 'dsd'])
- (1, 2, 3, 'dddfdfd', {'dsds': 'dsd'}, ['dsds', 'dsd'])
答案
4、默认参数:
预先赋值,如果调用过程中没有传值的话,就按照默认参数,有传值就用传的值。形象比喻:选举大会,先内定一个,如果没有新人参选
- def claa(x,y,z=3):
- a=x+y+z
- return a
- b=claa(1,4)
- print(b)
- >>>
- 8
使用情景:
一、
这样,大多数学生注册时不需要提供年龄和城市,只提供必须的两个参数:
- >>> enroll('Sarah', 'F')
- name: Sarah
- gender: F
- age: 6
- city: Beijing
果要继续传入年龄、城市等信息怎么办?这样会使得调用函数的复杂度大大增加。
我们可以把年龄和城市设为默认参数:
- def enroll(name, gender, age=6, city='Beijing'):
- print('name:', name)
- print('gender:', gender)
- print('age:', age)
- print('city:', city)
这样,大多数学生注册时不需要提供年龄和城市,只提供必须的两个参数:
- >>> enroll('Sarah', 'F')
- name: Sarah
- gender: F
- age: 6
- city: Beijing
只有与默认参数不符的学生才需要提供额外的信息:
- enroll('Bob', 'M', 7)
- enroll('Adam', 'M', city='Tianjin')
5.可变参数—*args
定义可变参数和定义一个list或tuple参数相比,仅仅在参数前面加了一个*
号。在函数内部,参数numbers
接收到的是一个tuple,因此,函数代码完全不变。但是,调用该函数时,可以传入任意个参数,包括0个参数:
顾名思义,可变参数就是传入的参数个数是可变的,可以是1个、2个到任意个,还可以是0个。这些可变参数在函数调用时自动组装为一个tuple。
*列表,
5.1用法:在写特定功能的时候,也许只有一个X值,加入参数组的话:可以为后期扩展处理多个值留下方便,不传的情况下为空值!函数内部打印的话:显示:()
- def casd(x,*args): #args才是参数,*是一个特殊用法【列表有关】
- print(x)
- print(args)
- q=casd(1,2,3,4,5,) #把剩余的参数传给后面的参数。
- print(q)
- >>>
- 1
- (2, 3, 4, 5)
- None
- def casd(x,*args): #
- print(x)
- print(args)
- q=casd(1,*[2,3,4,5]) →等价于:2,3,4,5
- >>>
- 1
- (2, 3, 4, 5)
- def casd(x,*args):
- print(x)
- print(args)
- q=casd(1,[2,3,4,5])
- >>>>
- 1
- ([2, 3, 4, 5],) print(args[0][o]) 会打印出X
5.2其他情况:所以Python允许你在list或tuple前面加一个*
号,把list或tuple的元素变成可变参数传进去:
- def calc(*numbers):
- sum = 0
- for n in numbers:
- sum = sum + n * n
- return sum
- nums = [1, 2, 3]
- calc(*nums)
- >>>
- 14
- def cala(x,*args):
- print(x)
- print(args)
- cala(1,*{'ssa':'sasa'})
- cala(1,*['ssa','sasa','hasattr']) #for i in 操作
- cala(1,['ssa','sasa','hasattr']) #整体一个元素
- def cala(x,*args):
- print(x)
- print(args)
- cala(1,{'ssa':'sasa'}) #整体一个元素
- cala(1,*{'ssa':'sasa'}) #for i in 操作取出里面的KEY
- >>>>
- {'dsds': 'dsd'}
- 1
- ('ssa',)
- 1
- ('ssa', 'sasa', 'hasattr')
- 1
- (['ssa', 'sasa', 'hasattr'],)
- 1
- ({'ssa': 'sasa'},)
- 1
- ('ssa',)
5.3 *args,**args传可变、关键字参数
- def cala(x,*args): #传入列表
- print(x)
- print(args)
- cala(1,'c',"ewe",'y',"ss")
- def cala(x,**args): #传入字典
- print(x)
- print(args)
- cala(1,c="ewe",y="ss")
- >>>
1
('c', 'ewe', 'y', 'ss')
1
{'y': 'ss', 'c': 'ewe'}
5.4、关键字参数 **kwargs
可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。而关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。请看示例:
- def cala(x,*args,**kwargs): #传入字典
- print(x)
- print(args)
- print(kwargs)
- cala(1,122121212,212,212,c="ewe",y="ss")
- >>
- 1
- (122121212, 212, 212)
- {'y': 'ss', 'c': 'ewe'}
①和可变参数类似,也可以先组装出一个dict,然后,把该dict转换为关键字参数传进去:
- def person(name, age, **kw):
- print('name:', name, 'age:', age, 'other:', kw)
- extra = {'city': 'Beijing', 'job': 'Engineer'}
- person('Jack', 24, city=extra['city'], job=extra['job'])
- >>>
- name: Jack age: 24 other: {'job': 'Engineer', 'city': 'Beijing'}
②、当然,上面复杂的调用可以用简化的写法:
- def person(name, age, **kw):
- print('name:', name, 'age:', age, 'other:', kw)
- extra = {'city': 'Beijing', 'job': 'Engineer'}
- person('Jack', 24, **extra) #简写方式
- >>>
- name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}
**extra
表示把extra
这个dict的所有key-value用关键字参数传入到函数的**kw
参数,kw
将获得一个dict,注意kw
获得的dict是extra
的一份拷贝,对kw
的改动不会影响到函数外的extra
。
5.1、 命名关键字参数
对于关键字参数,函数的调用者可以传入任意不受限制的关键字参数。至于到底传入了哪些,就需要在函数内部通过kw
检查。
参见廖海峰:http://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001431752945034eb82ac80a3e64b9bb4929b16eeed1eb9000
5.2、参数组合
在Python中定义函数,可以用必选参数、默认参数、可变参数、关键字参数和命名关键字参数,这5种参数都可以组合使用。但是请注意,参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。
- def f1(a, b, c=0, *args, **kw):
- print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)
- def f2(a, b, c=0, *, d, **kw):
- print('a =', a, 'b =', b, 'c =', c, 'd =', d, 'kw =', kw)
- >>>
- >>> f1(1, 2)
- a = 1 b = 2 c = 0 args = () kw = {}
- >>> f1(1, 2, c=3)
- a = 1 b = 2 c = 3 args = () kw = {}
- >>> f1(1, 2, 3, 'a', 'b')
- a = 1 b = 2 c = 3 args = ('a', 'b') kw = {}
- >>> f1(1, 2, 3, 'a', 'b', x=99)
- a = 1 b = 2 c = 3 args = ('a', 'b') kw = {'x': 99}
- >>> f2(1, 2, d=99, ext=None)
- a = 1 b = 2 c = 0 d = 99 kw = {'ext': None}
小结
Python的函数具有非常灵活的参数形态,既可以实现简单的调用,又可以传入非常复杂的参数。
默认参数一定要用不可变对象,如果是可变对象,程序运行时会有逻辑错误!
要注意定义可变参数和关键字参数的语法:
*args
是可变参数,args接收的是一个tuple;
**kw
是关键字参数,kw接收的是一个dict。
以及调用函数时如何传入可变参数和关键字参数的语法:
可变参数既可以直接传入:func(1, 2, 3)
,又可以先组装list或tuple,再通过*args
传入:func(*(1, 2, 3))
;
关键字参数既可以直接传入:func(a=1, b=2)
,又可以先组装dict,再通过**kw
传入:func(**{'a': 1, 'b': 2})
。
使用*args
和**kw
是Python的习惯写法,当然也可以用其他参数名,但最好使用习惯用法。
命名的关键字参数是为了限制调用者可以传入的参数名,同时可以提供默认值。
定义命名的关键字参数在没有可变参数的情况下不要忘了写分隔符*
,否则定义的将是位置参数。
备注:默认
python学习-day14:集合,函数,格式化的更多相关文章
- Python学习(二):函数入门
1.函数代码格式: def 函数名(): 函数内容 执行函数:函数名() 2.代码举例: #!/usr/bin/env python #coding=utf-8 #定义函数 def Func1(): ...
- Python 学习:常用函数整理
整理Python中常用的函数 一,把字符串形式的list转换为list 使用ast模块中的literal_eval函数来实现,把字符串形式的list转换为Python的基础类型list from as ...
- python学习道路(day4note)(函数,形参实参位置参数匿名参数,匿名函数,高阶函数,镶嵌函数)
1.函数 2种编程方法 关键词面向对象:华山派 --->> 类----->class面向过程:少林派 -->> 过程--->def 函数式编程:逍遥派 --> ...
- Python学习笔记 - day6 - 函数
函数 函数在编程语言中就是完成特定功能的一个词句组(代码块),这组语句可以作为一个单位使用,并且给它取一个名字.可以通过函数名在程序的不同地方多次执行(这叫函数的调用).函数在编程语言中有基本分为:预 ...
- Python学习笔记之函数
这篇文章介绍有关 Python 函数中一些常被大家忽略的知识点,帮助大家更全面的掌握 Python 中函数的使用技巧 1.函数文档 给函数添加注释,可以在 def 语句后面添加独立字符串,这样的注释被 ...
- 【Python学习之五】函数
环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 python3.6 Python不但能非常灵活地定义函数,而且本身内置 ...
- Python学习-第一天-函数和模块的使用
目录 Python学习-第一天总结 print输出的一种简单格式 函数参数之可变参数 模块管理函数 if else语句的单行实现(简洁) 变量作用域 函数书写格式 Python学习-第一天总结 pri ...
- 小甲鱼:Python学习笔记003_函数
>>> # 函数>>> def myFirstFunction(params1,params2...): print("这是我的第一个函数!") ...
- python学习 day14 (3月19日)----
04 json # 1. 用于多种语言 交互 编程语言通用数据 # 内置的 不需要安装直接导入使用 import json # 导入 # # dumps loads dump load # dic = ...
- python学习之map函数和reduce函数的运用
MapReduce:面向大型集群的简化数据处理引文 map()函数 Python中的map()函数接收两个参数,一个是调用函数对象(python中处处皆对象,函数未实例前也可以当对象一样调用),另一个 ...
随机推荐
- subplot demo
Y=[6484.05190614446 3479.60374683749 2326.82521799362 862.207727785871 423.711173743815 299.23540931 ...
- 转-浅谈HTTP-GET 、 HTTP-POST 和SOAP
HTTP-GET 和 HTTP-POST HTTP-GET和HTTP-POST是标准协议,他们使用HTTP(超文本传输协议)谓词(谓词是指条件表达式的求值返回真或假的过程.)对参数金星编码并将参数作为 ...
- C# 技巧(1) C# 转换时间戳
经常发现很多地方使用一个时间戳表示时间.比如: 1370838759 表示 2013年6月10日 12:32:39. 我们就需要一个工具,方便地转换这种时间格式 什么是时间戳? 时间戳, 又叫Uni ...
- iOS stringByEvaluatingJavaScriptFromString的参数长度限制
我不是十分确定传给stringByEvaluatingJavaScriptFromString的javascript脚本长度有限制 请看我下面代码: int l = 166235; data = [d ...
- POJ 3216 最小路径覆盖+floyd
Repairing Company Time Limit: 1000MS Memory Limit: 131072K Total Submissions: 6646 Accepted: 178 ...
- My Game --简介
曾经 我们雄心壮志,曾经 我们慷慨激昂,曾经 我们豪情满天涯. 曾经我们一起策划玩法,寻找背景题材,编写代码,幻想没有的更新.此刻由最后的孤狼把仅有成果分享给大伙. 所谓的玩法,背景,每个游戏都与众不 ...
- CENTOS/UBUNTU一键安装IPSEC/IKEV2 VPN服务器
1.在azure上创建ubuntu虚拟机 选择v15.04 server 版本 2.添加端口号 3.远程桌面到ubuntu 命令行 输入 sudo su 输入创建 ubuntu虚拟机 时候的 密码 ...
- DOM扩展之Selectors API
jQuery的核心就是通过CSS选择符查询DOM文档取得元素的引用,从而抛开了getElementById()和getElementsByTagName(). Selectors API致力于让浏览器 ...
- JQuery源码解析(十一)
内存泄露 什么是内存泄露? 内存泄露是指一块被分配的内存既不能使用,又不能回收,直到浏览器进程结束.在C++中,因为是手动管理内存,内存泄露是经常出现的事情.而现在流行的C#和Java等语言采用了自动 ...
- js中Math.round、parseInt、Math.floor和Math.ceil小数取整总结
Math.round.parseInt.Math.floor和Math.ceil 都可以返回一个整数,具体的区别请看下面的总结. 一.Math.round 作用:四舍五入,返回参数+0.5后,向下取整 ...