上节课总结

1 运算符

  in

   字符串 判断  : “hello” in "asdasfhelloasdfsadf"

   列表元素判断:"li" in ['li', 'ok']

   字典key判断:key in dic.keys()

2 基本的数据类型

 类名()  其实就是执行类的 __init__

         int()
__init__(self,args,base=10) int
a. 创建方式 两种
n1 = 123 # 根据int类,创建了一个对象
n2 = int(123) # 根据int类,创建了一个对象 类的实例化就是对象
b. int内部优化
1、n1 和 n2 的内存地址相同
n1 = 123
n2 = n1
2、按理说 n1 和 n2 的内存地址不相同
n1 = 123
n2 = 123
但是Python内部做了优化,
-5 ~ 257 以内的数,按照 2 的方式写时,都是指向同一个内存
n1 = 123
n2 = 123
除此以外的数,都是n1 和 n2 的内存地址不相同 python源码可以改取值范围
n1 = 123123
n2 = 123123
3、id查看对象的内存地址
n1 = 123
i1 = id(n1)
print(i1)
或者
i1 = id(123)
print(i1) c. int长度限制
-2**31 ~ 2 **31 -1
-2**63 ~ 2**63 - 1
       数字后有L 代表长整型
python 2.2之后,超过int的最大长度后,会自动转换成long类型,long类型无长度限制 python 3之后,int自己就无长度限制了 str,
a. 创建方式
s1 = "alex"
s1 = str('alex')
s1 = str('alex') #传参 字节和编码,可以加上编码方式
b. 特有功能
# 两端去除空格
# s1.strip() # 以 .. 开头
# s1.startswith() # 找子序列 "12","h"
# s1.find() # 将字符串中的某子序列替换成 指定的值
# s1.replace() # 变大写
# s1.upper() # 是。。。吗?
# s1.isalpha() c. 公共功能
索引:只能取一个元素
切片:取多个元素
len:
len("汉字")
3.5 ==》 字符 (utf-8 中 规定1个汉字3个字节,但是3版本中 1个汉字就是一个字符,不是字节。所以这里len是2)
2.7==》 字节(utf-8 中 规定1个汉字3个字节,所以这里len是6)
for:
3.5 ==》 字符 (3 版本中 循环汉字字符串不是字节,而是按照字符来进行循环的)
2.7==》 字节(2版本总循环汉字是以字节来循环的) 编码、for bytes方法:转换成字节
    3版本python中 汉字字符串循环不是按照字节循环,而是按照字符循环。
name = "李露"
for i in name:
print(i) #循环打印每个汉字而不是字节
bytes_list = bytes(i, encoding='utf-8') #将汉字转成字节,编码是utf-8
print(bytes_list)
for b in bytes_list:
#1、3.5 for循环时候,循环的每一个元素是 “字符”
#2、字符 =》 字节
bytes_list = bytes("字符串",encoding='utf-8') # utf-8 -> 3字节 1个汉字
# gbk -》 2字节 1个汉字
print(bytes_list) # 默认每一个字节都是16进制表示
for b in bytes_list:
print(b) # 默认每一个字节都是10进制表示 3、10进制的数字 ==》 2进制
len
id
bin(10进制的数字)
d、 bytes和str的转换 将字节转换成字符串 bytes方法
a = "李露"
# 将字符串转换成字节
b1 = bytes(a, encoding='utf-8')
print(b1)
b2 = bytes(a, encoding='gbk')
print(b2)
# 将字节转换成字符串 newa1 = str(b1, encoding="utf-8")
print(newa1) newa2 = str(b2, encoding='gbk')
print(newa2) ###########
x = str()
# 创建字符串
# 转换成字符串,字节,编码
m = bytes()
# 创建字节
# 转换成字节,字符串,要编程什么编码类型的字节 python进制转换
hex 可以 十进制转16进制 二进制转16进制 结果都是字符串
>>> hex(0b10)
'0x2'
>>> hex(10)
'0xa'
bin 可以十进制转2进制 16进制转2进制 结果都是字符串
>>> bin(10)
'0b1010'
>>> bin(0x2)
'0b10'
int 可以16进制转换十进制 2进制转换十进制
>>> int(0xe) >>> int(0b100)   list
可变元素的“集合” -----------
str -> 创建字符串,或者将其他的转换成字符串
------------------------------------------
list -> 创建列表,将其他元素转换成列表 a. 创建和转换
1、创建
li = [11,22,33,4]
li = list()
li = list([11,22,33,4])
2、转换 注:放可迭代的 凡是可以for循环的都可以迭代。 字符串 元组 字典 列表本身 都可以迭代
s1 = "李露"
# for,字符 ==> 可迭代
l1 = list(s1) # for循环,将循环的每一个元素,当做列表的元素
# ["李", "露"]
print(l1)          # 元组 转换成列表
# t2 = ("alex", "laonanhai", "seven")
# l2 = list(t2)
# print(l2) # 字典 转换成列表
# dic = {'k1': "alex", "k2": 'seven'}
# l3 = list(dic.items())
# print(l3)
# 字符串,元组,字典 =》 列表 b. 列表特有功能
# 追加
# li.append()
# 清除
# li.clear()
# 扩展自己,用另外一个可迭代的对象,扩充到自己内部
# str,list,dict,tuple
# s = "李露"
# li.extend(s)
# print(li)
# 翻转,自己内部元素翻转
# li.reverse()
# 向指定位置插入指定元素
# li.insert(1, "X")
c. 公共功能
li = ["alex", "eric", 'seven', 123]
索引:li[2]
切片:li[2:3]
del
       enumerate
for
len
       join
d. 多层列表 字典取值
li = ["alex", "eric", 'seven', 123]
li = [ "alex" , 123, {"k1":"v1", "k2": {"vv": (11,22,123), "ii": 456}}] li[2] --> {"k1":"v1", "k2": {"vv": 123, "ii": 456}}
li[2]['k2'] ==> {"vv": 123, "ii": 456}
li[2]['k2']["vv"] ==> (11,22,123)
li[2]['k2']["vv"][2] 元组 tuple 转换时候放可迭代的,即可以for循环取的类型。 比如 字符串 列表 字典都可以循环
a. 创建和转换
t = (11,22,33)
t = tuple((11,22,33))
t = tuple([]) # 字符串,列表,字典
b. 特有方法
count
index
c. 嵌套(元素不可修改) 注:如果元素是列表或者字典则可以修改
t = (11,22,33)
t = (11,22,["alex", {"k1": "v1"}]) e. 元组的特性,不可修改,谁不可被修改 #如果元素是列表或者字典可以修改
元组,儿子不能变
元组,儿子不能变,孙子,...       整理: 元组 字符串 特性总结
        一般字符串,执行一个功能,生成一个新内容,原来内容不变
        list,tuple,dict,执行一个功能,自身进行变化 上节总结 基本数据类型
**********************
列表一句转变成字典
li = [11,12,13]
dic = dict(enumerate(li,10))
print(11)
print(dic) **********************
2 版本 print(dic.keys()) 直接返回 一个列表 3 版本 print(dic.keys()) 返回的是一个类
**********************
fromkeys(seq,value=None) 解释:
        
默认不写value的话,所有的值为None
n = dict.fromkeys(['k1', 'k2'], []) #默认逗号后面不给的话,key对应的value都是None n['k1'].append(2) #我们修改逗号后面的空列表元素 打印 所有key的value也会修改
print(n) n['k1'] = 3 # 而单独修改key的value的话,只有 这个key的value改了,而其他的key对应的value都不变
print(n) n = dict.fromkeys() #默认逗号后面不给的话,key对应的value都是None
print(n)

1、set 集合

set集合,是一个无序且不重复的元素集合

 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 集合class

示例

 #!/usr/bin/env python
# _*_ coding:utf-8 _*_ a={1:2,4:5}
b=set(a) b.add(111111)
b.clear()
print(b) n = {11,22,33}
b = {22,66}
c = {11} # n中有的b中没有的赋值给新的变量 打印
new_n = n.difference(b)
print(new_n) #n中有的 b中没有的 更新到n
# n.difference_update(b)
# print(n) # 将迭代的序列加入
n.update("al")
n.update([1,3,4])
print(n) #n存在的b不存在的 b存在n不存在的 组合一起输出
ret=n.symmetric_difference(b)
ret2 = n.symmetric_difference({11,22,33})
print(ret)
print("=========")
# n存在的b不存在的 b存在n不存在的 组合一起 更新到前面的集合
n.symmetric_difference_update(b)
print(n) # 是否是子集 不是返回false 是的话True
ret = n.issubset(c) # n是不是c的子
print(ret)
ret1 = c.issubset(n) # c是不是n的子
print(ret1)
ret2 = n.issuperset(c) # n是不是c的父
print(ret2) # pop discard remove 三个删除的区别 #pop 删除同时可以获取到该值
ret = n.pop() #由于集合是无序的,所以pop删除也是无序的
print(ret)
# discard 删除集合元素,如果元素不存在 返回False 不报错
n.discard(11)
print(n)
#remove 删除集合元素 如果元素不存在 报错
#n.remove(99) z = {11,22,33}
p = {44} z.intersection(p) #取交集并更新到z中
print(z)

练习

 !/usr/bin/env python
# -*- coding:utf-8 -*-
# s1=set() #创建空的set集合
# s2={11,22,33,44,55} #直接创建set集合
# print(s2)
# l1=[11,22,33,44,22,11]
# l2=(11,22,11,22,333)
# l3="123"
# s3=set([11,22,33,22]) #传送可迭代的对象,转换成set集合
# s4=set(l3)
# print(set(l2)) se={11,22,33,55}
print(se)
se.add(44) #添加
print(se)
se.clear() #清除所有元素
print(se)
be={11,22,33}
ce={22,55}
print(be.difference(ce))#找be中存在。ce中不存在的set集合,返回值
print(ce.difference(be))#找ce中存在,be中不存在的set集合,返回值
be.difference_update(ce)#找be中存在,ce中不存在的,更新自己
print(be)
ae={11,22,33,444,555}
ae.discard(444) #移除元素,如果没有的话不报错
ae.remove(555)#移除元素,没有的话报错
print(ae)
ee={11,22,33,555}
fe={22,555,666,7,7665}
print(ee.intersection(fe)) #取A和B的交集,返回新值。原来的A和B不变,取交集,新创建一个set
ee.intersection_update(fe) #A和B的交集,不返回值,直接更新自己成这个交集,取交集,修改原来set
print(ee)
je={11,212,33,515}
ke={22,555,666,7,7665}
print(je.isdisjoint(ke))#判断A和B有没有交集,有交集返回False,么有交集返回True
me={11,212,33,515}
ne={11,33}
print(ne.issubset(me))#判读A是否是B的子序列。是否是子集
print(me.issuperset(ne))#判读A是否是B的父序列。是否是父集
oe={11,212,33,55}
print(oe.pop()) #随机取一个值,去掉,并且可以返回这个值
print(oe)
pe={11,22,33,555}
qe={22,555,666,7,7665}
print(pe.difference(qe))
print(qe.difference(pe))
print(pe.symmetric_difference(qe))#将不共有的元素,组成一个set集合,差集,创建新对象
pe.symmetric_difference_update(qe)#将不共有的元素,组成一个set集合,并更新原有集合,差集,改变原来
print(pe)
re={11,22,33,555}
se={22,555,666,7,7665}
print(re.union(se))#A和B合并到一起,并集
me={22,555,666,545422}
me.update([22,9,8])#更新,多个元素,集合、元组,set
print(me)

2、三目运算符

三元运算(三目运算),是对简单的条件语句的缩写。

 # 书写格式

 result = 值1 if 条件 else 值2

 # 如果条件成立,那么将 “值1” 赋值给result变量,否则,将“值2”赋值给result变量
 name = "eric" if 1 == 1 else "alex"
print("==",name)

3、深浅拷贝

#str一次性创建,不能被修改。只要修改,重新创建
#list tuple 等,链表下一个元素的位置,上一个元素的位置,在本身做修改

1、对于 数字 和 字符串 而言,赋值、浅拷贝和深拷贝无意义,因为其永远指向同一个内存地址。

 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))

2、其他基本数据类型

对于字典、元祖、列表 而言,进行赋值、浅拷贝和深拷贝时,其内存地址的变化是不同的。

1、赋值

赋值,只是创建一个变量,该变量指向原来内存地址,如:

 n1 = {"k1": "wu", "k2": 123, "k3": ["alex", 456]}
n2 = n1

2、浅拷贝

浅拷贝,在内存中只额外创建第一层数据

 import copy

 n1 = {"k1": "wu", "k2": 123, "k3": ["alex", 456]}

 n3 = copy.copy(n1)

3、深拷贝

深拷贝,在内存中将所有的数据重新创建一份(排除最后一层,即:python内部对字符串和数字的优化)

 import copy

 n1 = {"k1": "wu", "k2": 123, "k3": ["alex", 456]}

 n4 = copy.deepcopy(n1)

4、函数

1、背景

1、面向过程编程
即:根据业务逻辑从上到下实现功能,其往往用一长段代码来实现指定功能,开发过程中最常见的操作就是粘贴复制,也就是将之前实现的代码块复制到现需功能处。
2、函数式编程
将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可
3、面向对象
对函数进行分类和封装,让开发“更快更好更强...”
 
函数式编程最重要的是增强代码的重用性和可读性
 
2、定义和使用
 def 函数名(参数):

     ...
函数体
...
返回值
函数的定义主要有如下要点:
  • def:表示函数的关键字
  • 函数名:函数的名称,日后根据函数名调用函数
  • 函数体:函数中进行一系列的逻辑计算,如:发送邮件、计算出 [11,22,38,888,2]中的最大数等...
  • 参数:为函数体提供数据
  • 返回值:当函数执行完毕后,可以给调用者返回数据。
    • 1、return xxx None
    • 2、一旦遇到return,函数内部的return一下不执行

 2.1 返回值

函数是一个功能块,该功能到底执行成功与否,需要通过返回值来告知调用者。
以上要点中,比较重要有参数和返回值:
 def 发送短信():

     发送短信的代码...

     if 发送成功:
return True
else:
return False while True: # 每次执行发送短信函数,都会将返回值自动赋值给result
# 之后,可以根据result来写日志,或重发等操作 result = 发送短信()
if result == False:
记录日志,短信发送失败...
2.2 、参数
为什么要有参数?
1、形参、实参
2、数量要一直,一一对应
3、指定参数
fun1(p="xxx",q="xxxx")
4、默认参数
默认参数可传可不传,可以覆盖
放在参数的尾部
5、动态参数
*args
**kwargs
6、万能参数
 
 
 普通参数
 # ######### 定义函数 ######### 

 # 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') 注:默认参数需要放在参数列表最后

默认参数

动态参数1

 动态参数,参数转成元组
def func(*args): print args # 执行方式一
func(11,33,4,4454,5) # 执行方式二
li = [11,2,2,3,3,4,54]
func(*li)

动态参数

如果 元素参数是一个列表呢?我们把列表传入输出的一个元素是列表,但是我们想把列表的每个元素当一个参数。调用的时候加*

 #!/usr/bin/env python
# _*_ coding:utf-8 _*_ a=[1,3,4]
def fuc(*args):
#print(args)
return args
ret=fuc(a)
print(ret) 结果:
C:\Python35\python3.exe E:/py_test/s4/s5.py
([1, 3, 4],) #!/usr/bin/env python
# _*_ coding:utf-8 _*_ a=[1,3,4]
def fuc(*args):
#print(args)
return args
ret=fuc(*a)
print(ret)
C:\Python35\python3.exe E:/py_test/s4/s5.py
(1, 3, 4)

动态参数2

 def func(**kwargs):

     print args

 # 执行方式一
func(name='wupeiqi',age=18) # 执行方式二
li = {'name':'wupeiqi', age:18, 'gender':'male'}
func(**li) 动态参数2 :**kwargs **kwargs 意指可以传入多个元素以key= value key的格式是按照变量名的命名规范为标准的

动态参数2

如果 元素参数是一个字典呢?我们把列表传入输出的一个元素是字典,但是我们想把字典的每个key value当一个参数。调用的时候加** 只加*是key

 #!/usr/bin/env python
# _*_ coding:utf-8 _*_ a={"k1":2,"k2":3}
def fuc(**args):
#print(args)
return args
ret=fuc(**a)
print(ret) C:\Python35\python3.exe E:/py_test/s4/s5.py
{'k1': 2, 'k2': 3}

动态参数3

 def func(*args, **kwargs):

     print args
print kwargs 万能参数

动态参数3

 #!/usr/bin/env python
# _*_ coding:utf-8 _*_
a={"k1":2,"k2":3}
b=[1,2,3]
def fuc(*args,**kwargs):
#print(args)
return args,kwargs
ret=fuc(*b,**a)
print(ret) C:\Python35\python3.exe E:/py_test/s4/s5.py
((1, 2, 3), {'k2': 3, 'k1': 2})

扩展:发送邮件实例

 #!/usr/bin/env python
# _*_ coding:utf-8 _*_
__author__ = 'liujianzuo' def email(p,text,subject):
import smtplib
from email.mime.text import MIMEText
from email.utils import formataddr ret = True
try: msg = MIMEText(text, 'plain', 'utf-8')
msg['From'] = formataddr(["武沛齐",'wptawy@126.com'])
msg['To'] = formataddr(["走人",'424662508@qq.com'])
msg['Subject'] = subject server = smtplib.SMTP("smtp.126.com", 25)
server.login("wptawy@126.com", "WW.3945.59")
server.sendmail('wptawy@126.com', [p,], msg.as_string())
server.quit()
except:
ret = False
return ret r1=email("1223995142@qq.com","python test email +===","subject==pyhon")
if r1:
print("发生成功")
else:
print("发送失败")

3、全局变量、局部变量

函数外的变量定义的全局变量,在函数内部修改不了,因为,函数内部需要global一下否则在函数内部只能是局部变量,只是变量名跟全局变量相同而已

 #全局变量一般以大写命名,局部变量以小写命名
#全局变量
p=234
def f1():
#局部变量
a=123
p=999 #全局变量在内部被修改。只在内部起作用
global p #应用到全局变量。
print(p)
print(a)
def f2():
#局部变量
a=456
print(p)
print(a)
f1()
f2()
output:
      999
      123
      999       456
 总结
全局变量:
大写
修改,global
局部变量:
小写,仅仅在代码块中能用

Python作用域

命名空间和作用域

命名空间一共分为三种:

  全局命名空间

  局部命名空间

  内置命名空间

*内置命名空间中存放了python解释器为我们提供的名字:input,print,str,list,tuple...它们都是我们熟悉的,拿过来就可以用的方法。

三种命名空间之间的加载与取值顺序:

加载顺序:内置命名空间(程序运行前加载)->全局命名空间(程序运行中:从上到下加载)->局部命名空间(程序运行中:调用时才加载)

取值顺序:

  在局部调用:局部命名空间->全局命名空间->内置命名空间

  在全局调用:全局命名空间->内置命名空间

综上所述,在找寻变量时,从小范围,一层一层到大范围去找寻。

作用域

作用域就是作用范围,按照生效范围可以分为全局作用域和局部作用域。

全局作用域:包含内置名称空间、全局名称空间,在整个文件的任意位置都能被引用、全局有效

局部作用域:局部名称空间,只能在局部范围生效

globals和locals方法

print(globals())
print(locals())
def func():
a = 12
b = 20
print(locals())
print(globals()) func()

output:

{'a': 12, 'b': 20}
{'__name__': '__main__', '__doc__': '\n装饰器\ndef outer(func):\n def inner():\n print("123")\n r=func()\n print("456")\n return r\n return inner\n\n@outer\ndef index():\n print(1)\n return 111\n\na=index()\nprint(a)\n', '__package__': None, '__builtins__': <module 'builtins' (built-in)>, '__spec__': None, '__file__': 'E:/py/55/learn-python/oldboy/temp.py', '__cached__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000026197831518>, 'func': <function func at 0x00000261977E9158>}

在局部调用locals和globals

global关键字,nonlocal关键字。

global:

  1,声明一个全局变量。

  2,在局部作用域想要对全局作用域的全局变量进行修改时,需要用到 global(限于字符串,数字)。

def func():
global a
a = 3
func()
print(a) count = 1
def search():
global count
count = 2
search()
print(count)
output:

  3
  2

global关键字举例

ps:对可变数据类型(list,dict,set)可以直接引用不用通过global。

li = [1,2,3]
dic = {'a':'b'} def change():
li.append('a')
dic['q'] = 'g'
print(dic)
print(li)
change()
print(li)
print(dic)

 

output:

{'q': 'g', 'a': 'b'}
 [1, 2, 3, 'a']
 [1, 2, 3, 'a']
 {'q': 'g', 'a': 'b'}

对于可变数据类型的应用举例

nonlocal:

  1,不能修改全局变量。

  2,在局部作用域中,对父级作用域(或者更外层作用域非全局作用域)的变量进行引用和修改,并且引用的哪层,从那层及以下此变量全部发生改变。

def add_b():
b = 42
def do_global():
b = 10
print(b)
def dd_nonlocal():
nonlocal b
b = b + 20
print(b)
dd_nonlocal()
print(b)
do_global()
print(b)
add_b()

 

output:

 10
  30
  30
  42

nonlocal关键字举例

函数的嵌套和作用域

函数的嵌套调用

def max2(x,y):
m = x if x>y else y
return m def max4(a,b,c,d):
res1 = max2(a,b)
res2 = max2(res1,c)
res3 = max2(res2,d)
return res3 # max4(23,-7,31,11)
output:

函数的嵌套定义

def f1():
print("in f1")
def f2():
print("in f2") f2()
f1()
###########
def f1():
def f2():
def f3():
print("in f3")
print("in f2")
f3()
print("in f1")
f2() f1()

  

output:

in f1
  in f2
  in f1
  in f2
  in f3

函数的嵌套定义

函数的作用域链:小范围作用域可以使用大范围的变量,但是反之不行,他是单向的。

def f1():
a = 1
def f2():
def f3():
print(a)
f3()
f2() f1()
################
def f1():
a = 1
def f2():
a = 2
f2()
print('a in f1 : ',a) f1()

 

output:

 1
  a in f1 : 1


作用域链应用举例

函数名的本质

函数名本质上就是函数的内存地址。

1.可以被引用

def func():
print('in func') f = func
print(f)
output:

<function func at 0x0000014DD0FB9158>

2.可以被当作容器类型的元素

def f1():
print('f1') def f2():
print('f2') def f3():
print('f3') l = [f1,f2,f3]
d = {'f1':f1,'f2':f2,'f3':f3}
#调用
l[0]()
d['f2']() 加了括号就是执行

 

output:

 f1
  f2

可以当做容器类型的元素

3.可以当作函数的参数和返回值

def f1():
print('f1') def func1(argv):
argv()
return argv f = func1(f1)
f()

 

output:

 f1
  f1


可以当做函数的参数和返回值
第一类对象(first-class object)指
1.可在运行期创建
2.可用作函数参数或返回值
3.可存入变量的实体。

闭包

def func():
name = '太白金星'
def inner():
print(name)

  

闭包函数:

内部函数包含对外部作用域而非全剧作用域变量的引用,该内部函数称为闭包函数
#函数内部定义的函数称为内部函数

由于有了作用域的关系,我们就不能拿到函数内部的变量和函数了。如果我们就是想拿怎么办呢?返回呀!

我们都知道函数内的变量我们要想在函数外部用,可以直接返回这个变量,那么如果我们想在函数外部调用函数内部的函数呢?

是不是直接就把这个函数的名字返回就好了?

这才是闭包函数最常用的用法

def func():
name = 'eva'
def inner():
print(name)
return inner f = func()
f()
output:eva

判断闭包函数的方法__closure__

#输出的__closure__有cell元素 :是闭包函数
def func():
name = 'eva'
def inner():
print(name)
print(inner.__closure__)
return inner f = func()
f() #输出的__closure__为None :不是闭包函数
name = 'egon'
def func2():
def inner():
print(name)
print(inner.__closure__)
return inner f2 = func2()
f2()

  

def wrapper():
money = 1000
def func():
name = 'eva'
def inner():
print(name,money)
return inner
return func f = wrapper()
i = f()
i() eva 1000 闭包嵌套

  

from urllib.request import urlopen
def but():
content = urlopen("http://www.cnblogs.com/jin-xin/articles/8259929.html").read()
def get_content():
return content
return get_content
fn = but()
content = fn() # 获取内容
print(content.decode('utf-8')) #中文显示
content2 = fn() # 重新获取内容
print(content2.decode('utf-8')) 闭包的网络应用

  

练习题

1、简述普通参数、指定参数、默认参数、动态参数的区别

 """
普通参数:单个是单个,多个是多个,有多少个,调用的时候就要传几个,按照顺序赋值,
默认参数:只能放在 普通参数后面,不能放到前面 ,不给值的话,就用默认的参数值
指定参数:不按照顺序,想指定给谁就给谁。
动态参数:*args *kwargs 当然不一定非要叫args 规范而已。*args这些参数自动组装成一个元组,**kwargs自动组装层字典 即调用的时候 传列表 key value
"""

2、写函数,计算传入字符串中【数字】、【字母】、【空格] 以及 【其他】的个数

 #!/usr/bin/env python
# -*- coding:utf-8 -*- st=raw_input("str:")
def count_str(a):
sz=zm=kg=qt=0
# temp=str(a)
for i in a:
# print i
if i.isdigit():
sz+=1
elif i.isalpha():
zm+=1
elif i.isspace():
kg+=1
else:
qt+=1
return (sz,zm,kg,qt)
jg=count_str(st)
print jg

3、写函数,判断用户传入的对象(字符串、列表、元组)长度是否大于5。

 def obj_len(args):
if isinstance(args,str) or isinstance(args,list) or isinstance(args,tuple):
if len(args)>5:
return True
else:
return False
else:
return None
st="jkljkjlj"
lis=[11,22,33,44,55]
tup=(11,22,33,44,55,66)
print obj_len(st),obj_len(lis),obj_len(tup)

4、写函数,检查用户传入的对象(字符串、列表、元组)的每一个元素是否含有空内容。

 def has_space(args):
if isinstance(args,str) or isinstance(args,list) or isinstance(args,tuple):
for i in args:
if i == " ":
return True
break
else:
return False
else:
return None
st="jkljkjlj"
lis=[11,22,33,44,55," "]
tup=(11,22,33,44,55,66," ")
print has_space(st),has_space(lis),has_space(tup)

5、写函数,检查传入列表的长度,如果大于2,那么仅保留前两个长度的内容,并将新内容返回给调用者。

 # def fun(args):
# if len(args)>2:
# ret=args[0:2]
# return ret
# else:
# return args
# # return args 也可以不写else直接这样写
# inp=[11,22,33,44,55]
# print fun(inp) --------------------
def fun2(args):
if len(args)>2:
del args[2:]
li=[11,22,33,444,55]
fun2(li)
print li

6、写函数,检查获取传入列表或元组对象的所有奇数位索引对应的元素,并将其作为新列表返回给调用者。

 def fun(x):
ret=x[1::2]
return ret
inp=[11,22,33,44,55]
print fun(inp)

7、写函数,检查传入字典的每一个value的长度,如果大于2,那么仅保留前两个长度的内容,并将新内容返回给调用者。

dic = {"k1""v1v1""k2": [11,22,33,44]}
 
PS:字典中的value只能是字符串或列表

 dic = {"k1": "v1v1", "k2": [11,22,33,44],"k3":"ca","k4":[11,22]}
def fun(x):
di={}
for i,j in x.items():
# print i,j
if len(j)>2:
di[i] = j[:2]
else:
di[i] = j
return di
ret=fun(dic)
print ret

8、写函数,利用递归获取斐波那契数列中的第 10 个数,并将该值返回给调用者。

python基础-3 集合 三元运算 深浅拷贝 函数 Python作用域的更多相关文章

  1. Python全栈之路3--set集合--三元运算--深浅拷贝--初识函数

    一.上节课的重点回顾: 1.类名加括号其实就是执行类的__init__方法: 2.int a.创建方式 n1 = 123 #根据int类创建了一个对象 n2 = int(123) #根据int类创建一 ...

  2. python基础(三元运算+深浅拷贝+函数参数)

    三元运算 三元运算,又称三目运算,主要作用是减少代码量,是对简单的条件语句的缩写. 书写格式: result = 值1 if 条件 else 值2 即如果条件成立,则将值1赋给result变量,如果不 ...

  3. python基础知识5——赋值与深浅拷贝——整数和字符串,列表元组字典

    深浅copy 一.数字和字符串 对于 数字 和 字符串 而言,赋值.浅拷贝和深拷贝无意义,因为其永远指向同一个内存地址. 1 import copy 2 # ######### 数字.字符串 #### ...

  4. Python编码、集合set、深浅拷贝

    编码 : a.encode(' ')     windows 默认编码GBK ASCII : 最早的编码. ⾥⾯有英⽂⼤写字⺟, ⼩写字⺟, 数字, ⼀些特殊字符.没有中⽂, 8个01代码, 8个bi ...

  5. python基础——10(三元运算符、匿名函数)

    一.三元运算符 本质是if--else--的语法糖 前提:简化if--else--的结构,且两个分支有且只有一条语句 案例: a = 20 b = 30 res = a if a > b els ...

  6. Python基础知识总结笔记(四)函数

    Python基础知识总结笔记(四)函数python中的函数函数中的参数变量作用域偏函数PFA递归函数高阶函数BIFs中的高阶函数匿名函数lambda闭包Closure装饰器Decorator函数式编程 ...

  7. python基础之数据类型操作补充,集合及其操作,深浅拷贝

    内容概要: 数据类型操作补充 集合及其操作 深浅拷贝1.基础数据类型补充 1.1字符串的操作补充li = ["李嘉诚", "麻花藤", "黄海峰&qu ...

  8. python基础数据类型--集合(set)

    python基础数据类型--集合(set) 集合是一个数学概念由一个或多个确定的元素所构成的整体叫做集合 集合中的三个特征 1.确定性(元素必须死可hash) 2.互异性(去重) 3.无序性(集合中的 ...

  9. 『Python基础-5』数字,运算,转换

    『Python基础-5』数字,运算,转换 目录 基本的数字类型 二进制,八进制,十六进制 数字类型间的转换 数字运算 1. 数字类型 Python 数字数据类型用于存储数学上的值,比如整数.浮点数.复 ...

随机推荐

  1. CentOS7 安装 Mysql5.6.40

    CentOS7.5二进制安装MySQL-5.6.40 安装之后登陆不上,mysql.user 表是空的时: Mysql User表为空 mysql创建用户报错ERROR 1364 (HY000): F ...

  2. 03javascript01

    1.javascript语法体系 1)EMCA基础语法(统一) 2)BOM编程(不统一) 3)DOM编程(不统一) 1.1 javascript使用 <!DOCTYPE html> < ...

  3. UVa11806 Cheerleaders(容斥原理)

    11806 - Cheerleaders Time limit: 2.000 seconds C Cheerleaders In most professional sporting events, ...

  4. 1125. Chain the Ropes (25)

    Given some segments of rope, you are supposed to chain them into one rope. Each time you may only fo ...

  5. php内置函数分析之array_diff_assoc()

    static void php_array_diff_key(INTERNAL_FUNCTION_PARAMETERS, int data_compare_type) /* {{{ */ { uint ...

  6. 基于python3环境下搭建Robot Framework 自动化测试框架(一)

    大家都知道,Robot Framework 是基于python2 环境 的一套自动化测试工具,据说python 2 到2020年不维护,现在用python 3 的环境搭建Robot Framework ...

  7. 关于在IOS中 contenteditable=true 无法输入的问题

    解决: 1.添加样式-webkit-user-select:text 2.如果引入了fastclick,需要添加个类名 needsclick 来源于知乎(https://www.zhihu.com/q ...

  8. Python---进阶---logging---装饰器打印日志

    #### logging - logging.debug - logging.info - logging.warning - logging.error - logging.critical --- ...

  9. 049:ORM常用Field详解(1)

    常用字段: 在 Django 中,定义了一些 Field 来与数据库表中的字段类型来进行映射.以下将介绍那些常用的字段类型. AutoField: 映射到数据库中是 int 类型,可以有自动增长的特性 ...

  10. sql server 修改表字段

    1.添加表说明 EXECUTE sp_addextendedproperty N'MS_Description','表说明',N'user',N'dbo',N'table',N'表名',NULL,NU ...