python基础-3 集合 三元运算 深浅拷贝 函数 Python作用域

上节课总结

1 运算符 

  in

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

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

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

2 基本的数据类型

  1 类名()  其实就是执行类的 __init__
  2         
  3         int()
  4             __init__(self,args,base=10)
  5     
  6 int
  7         a. 创建方式 两种
  8             n1 = 123      # 根据int类,创建了一个对象
  9             n2 = int(123) # 根据int类,创建了一个对象 类的实例化就是对象
 10         b. int内部优化
 11             1、n1 和 n2 的内存地址相同
 12                 n1 = 123
 13                 n2 = n1
 14             2、按理说 n1 和 n2 的内存地址不相同
 15                 n1 = 123
 16                 n2 = 123
 17             但是Python内部做了优化,
 18                 -5 ~ 257 以内的数,按照 2 的方式写时,都是指向同一个内存
 19                     n1 = 123
 20                     n2 = 123
 21                 除此以外的数,都是n1 和 n2 的内存地址不相同  python源码可以改取值范围
 22                     n1 = 123123
 23                     n2 = 123123
 24             3、id查看对象的内存地址
 25                     n1 = 123
 26                     i1 = id(n1)
 27                     print(i1)
 28                 或者
 29                     i1 = id(123)
 30                     print(i1)
 31     
 32         c. int长度限制
 33    -2**31 ~ 2 **31 -1
 34    -2**63 ~ 2**63 - 1
 35        数字后有L 代表长整型
 36             python 2.2之后,超过int的最大长度后,会自动转换成long类型,long类型无长度限制
 37             
 38             python 3之后,int自己就无长度限制了
 39 
 40         
 41     str,
 42         a. 创建方式
 43             s1 = "alex"
 44             s1 = str('alex')
 45             s1 = str('alex') #传参 字节和编码,可以加上编码方式
 46         b. 特有功能
 47             # 两端去除空格
 48             # s1.strip()
 49 
 50             # 以 .. 开头
 51             # s1.startswith()
 52 
 53             # 找子序列 "12","h"
 54             # s1.find()
 55 
 56             # 将字符串中的某子序列替换成 指定的值
 57             # s1.replace()
 58 
 59             # 变大写
 60             # s1.upper()
 61 
 62             # 是。。。吗?
 63             # s1.isalpha()
 64             
 65         c. 公共功能
 66             索引:只能取一个元素
 67             切片:取多个元素
 68             len:
 69                 len("汉字")
 70                 3.5 ==》 字符  (utf-8 中 规定1个汉字3个字节,但是3版本中 1个汉字就是一个字符,不是字节。所以这里len是2)
 71                 2.7==》 字节(utf-8 中 规定1个汉字3个字节,所以这里len是6)
 72             for 73                 3.5 ==》 字符  (3 版本中 循环汉字字符串不是字节,而是按照字符来进行循环的)
 74                 2.7==》 字节(2版本总循环汉字是以字节来循环的)
 75                 
 76             编码、for   bytes方法:转换成字节
 77     3版本python中 汉字字符串循环不是按照字节循环,而是按照字符循环。
 78                 name = "李露"
 79                 for i in name:
 80                     print(i) #循环打印每个汉字而不是字节
 81                     bytes_list = bytes(i, encoding='utf-8')  #将汉字转成字节,编码是utf-8
 82                     print(bytes_list)
 83                     for b in bytes_list:
 84                         #1、3.5 for循环时候,循环的每一个元素是 “字符”
 85                         #2、字符 =》 字节
 86                     bytes_list = bytes("字符串",encoding='utf-8')
 87                     
 88                         # utf-8 -> 3字节 1个汉字
 89                         # gbk   -》 2字节 1个汉字
 90                     print(bytes_list) # 默认每一个字节都是16进制表示
 91                     for b in bytes_list:
 92                         print(b)      # 默认每一个字节都是10进制表示
 93                 
 94                 3、10进制的数字 ==》 2进制
 95                     len
 96                     id
 97                     bin(10进制的数字)
 98         d、 bytes和str的转换   将字节转换成字符串 bytes方法
 99                 a = "李露"
100                 # 将字符串转换成字节
101                 b1 = bytes(a, encoding='utf-8')
102                 print(b1)
103                 b2 = bytes(a, encoding='gbk')
104                 print(b2)
105                 # 将字节转换成字符串
106 
107                 newa1 = str(b1, encoding="utf-8")
108                 print(newa1)
109 
110                 newa2 = str(b2, encoding='gbk')
111                 print(newa2)
112 
113 
114                 ###########
115                 x = str()
116                 # 创建字符串
117                 # 转换成字符串,字节,编码
118                 m = bytes()
119                 # 创建字节
120                 # 转换成字节,字符串,要编程什么编码类型的字节
121 
122 python进制转换
123 hex 可以 十进制转16进制   二进制转16进制    结果都是字符串
124 >>> hex(0b10)
125 '0x2'
126 >>> hex(10)
127 '0xa'
128 bin 可以十进制转2进制  16进制转2进制   结果都是字符串
129 >>> bin(10)
130 '0b1010'
131 >>> bin(0x2)
132 '0b10'
133 int 可以16进制转换十进制 2进制转换十进制 
134 >>> int(0xe)         
135                   
136 >>> int(0b100)       
137                    
138  
139 
140     list
141         可变元素的“集合”
142         
143         -----------
144         str -> 创建字符串,或者将其他的转换成字符串
145         ------------------------------------------
146         list -> 创建列表,将其他元素转换成列表
147         
148         a. 创建和转换
149             1、创建
150                 li = [11,22,33,4]
151                 li = list()
152                 li = list([11,22,33,4]) 
153             2、转换  注:放可迭代的 凡是可以for循环的都可以迭代。  字符串 元组 字典 列表本身 都可以迭代
154                 s1 = "李露"
155                 # for,字符 ==> 可迭代
156                 l1 = list(s1) # for循环,将循环的每一个元素,当做列表的元素
157                 # ["李", "露"]
158                 print(l1)
159                         
160          # 元组 转换成列表
161                 # t2 = ("alex", "laonanhai", "seven")
162                 # l2 = list(t2)
163                 # print(l2)
164 
165                 # 字典  转换成列表
166                 # dic = {'k1': "alex", "k2": 'seven'}
167                 # l3 = list(dic.items())
168                 # print(l3)
169                 # 字符串,元组,字典 =》 列表
170 
171         b. 列表特有功能
172             # 追加
173             # li.append()
174             # 清除
175             # li.clear()
176             # 扩展自己,用另外一个可迭代的对象,扩充到自己内部
177             # str,list,dict,tuple
178             # s = "李露"
179             # li.extend(s)
180             # print(li)
181             # 翻转,自己内部元素翻转
182             # li.reverse()
183             # 向指定位置插入指定元素
184             # li.insert(1, "X")
185         c. 公共功能
186             li = ["alex", "eric", 'seven', 123]
187             索引:li[2]
188             切片:li[2:3]
189             del
190        enumerate
191             for
192             len
193         join
194         d. 多层列表 字典取值
195             li = ["alex", "eric", 'seven', 123]
196             li = [ "alex" , 123, {"k1":"v1", "k2": {"vv": (11,22,123), "ii": 456}}]
197             
198             li[2] --> {"k1":"v1", "k2": {"vv": 123, "ii": 456}}
199             li[2]['k2'] ==> {"vv": 123, "ii": 456}
200             li[2]['k2']["vv"] ==> (11,22,123)
201             li[2]['k2']["vv"][2]
202                 
203     元组 tuple   转换时候放可迭代的,即可以for循环取的类型。 比如  字符串  列表 字典都可以循环
204         a. 创建和转换
205             t = (11,22,33)
206             t = tuple((11,22,33))  
207             t = tuple([]) # 字符串,列表,字典
208         b. 特有方法
209             count
210             index
211         c. 嵌套(元素不可修改) 注:如果元素是列表或者字典则可以修改
212             t = (11,22,33)
213             t = (11,22,["alex", {"k1": "v1"}])
214 
215             
216         e. 元组的特性,不可修改,谁不可被修改  #如果元素是列表或者字典可以修改
217             元组,儿子不能变
218             元组,儿子不能变,孙子,...
219             
220       整理: 元组 字符串 特性总结
221           一般字符串,执行一个功能,生成一个新内容,原来内容不变
222           list,tuple,dict,执行一个功能,自身进行变化
223 
224 上节总结 基本数据类型        
**********************
列表一句转变成字典
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集合,是一个无序且不重复的元素集合

  1 class set(object):
  2     """
  3     set() -> new empty set object
  4     set(iterable) -> new set object
  5      
  6     Build an unordered collection of unique elements.
  7     """
  8     def add(self, *args, **kwargs): # real signature unknown
  9         """
 10         Add an element to a set,添加元素
 11          
 12         This has no effect if the element is already present.
 13         """
 14         pass
 15  
 16     def clear(self, *args, **kwargs): # real signature unknown
 17         """ Remove all elements from this set. 清楚内容"""
 18         pass
 19  
 20     def copy(self, *args, **kwargs): # real signature unknown
 21         """ Return a shallow copy of a set. 浅拷贝  """
 22         pass
 23  
 24     def difference(self, *args, **kwargs): # real signature unknown
 25         """
 26         Return the difference of two or more sets as a new set. A中存在,B中不存在
 27          
 28         (i.e. all elements that are in this set but not the others.)
 29         """
 30         pass
 31  
 32     def difference_update(self, *args, **kwargs): # real signature unknown
 33         """ Remove all elements of another set from this set.  从当前集合中删除和B中相同的元素"""
 34         pass
 35  
 36     def discard(self, *args, **kwargs): # real signature unknown
 37         """
 38         Remove an element from a set if it is a member.
 39          
 40         If the element is not a member, do nothing. 移除指定元素,不存在不保错
 41         """
 42         pass
 43  
 44     def intersection(self, *args, **kwargs): # real signature unknown
 45         """
 46         Return the intersection of two sets as a new set. 交集
 47          
 48         (i.e. all elements that are in both sets.)
 49         """
 50         pass
 51  
 52     def intersection_update(self, *args, **kwargs): # real signature unknown
 53         """ Update a set with the intersection of itself and another.  取交集并更更新到A中 """
 54         pass
 55  
 56     def isdisjoint(self, *args, **kwargs): # real signature unknown
 57         """ Return True if two sets have a null intersection.  如果没有交集,返回True,否则返回False"""
 58         pass
 59  
 60     def issubset(self, *args, **kwargs): # real signature unknown
 61         """ Report whether another set contains this set.  是否是子序列"""
 62         pass
 63  
 64     def issuperset(self, *args, **kwargs): # real signature unknown
 65         """ Report whether this set contains another set. 是否是父序列"""
 66         pass
 67  
 68     def pop(self, *args, **kwargs): # real signature unknown
 69         """
 70         Remove and return an arbitrary set element.
 71         Raises KeyError if the set is empty. 移除元素
 72         """
 73         pass
 74  
 75     def remove(self, *args, **kwargs): # real signature unknown
 76         """
 77         Remove an element from a set; it must be a member.
 78          
 79         If the element is not a member, raise a KeyError. 移除指定元素,不存在保错
 80         """
 81         pass
 82  
 83     def symmetric_difference(self, *args, **kwargs): # real signature unknown
 84         """
 85         Return the symmetric difference of two sets as a new set.  对称交集
 86          
 87         (i.e. all elements that are in exactly one of the sets.)
 88         """
 89         pass
 90  
 91     def symmetric_difference_update(self, *args, **kwargs): # real signature unknown
 92         """ Update a set with the symmetric difference of itself and another. 对称交集,并更新到a中 """
 93         pass
 94  
 95     def union(self, *args, **kwargs): # real signature unknown
 96         """
 97         Return the union of sets as a new set.  并集
 98          
 99         (i.e. all elements that are in either set.)
100         """
101         pass
102  
103     def update(self, *args, **kwargs): # real signature unknown
104         """ Update a set with the union of itself and others. 更新 """
105         pass
106 
107 set 集合class
View Code

示例

 1 #!/usr/bin/env python
 2 # _*_ coding:utf-8 _*_
 3 
 4 a={1:2,4:5}
 5 b=set(a)
 6 
 7 b.add(111111)
 8 b.clear()
 9 print(b)
10 
11 n = {11,22,33}
12 b = {22,66}
13 c = {11}
14 
15 # n中有的b中没有的赋值给新的变量 打印
16 new_n = n.difference(b)
17 print(new_n)
18 
19 #n中有的 b中没有的 更新到n
20 # n.difference_update(b)
21 # print(n)
22 
23 # 将迭代的序列加入
24 n.update("al")
25 n.update([1,3,4])
26 print(n)
27 
28 #n存在的b不存在的 b存在n不存在的 组合一起输出
29 ret=n.symmetric_difference(b)
30 ret2 = n.symmetric_difference({11,22,33})
31 print(ret)
32 print("=========")
33 # n存在的b不存在的 b存在n不存在的 组合一起 更新到前面的集合
34 n.symmetric_difference_update(b)
35 print(n)
36 
37 #  是否是子集  不是返回false  是的话True
38 ret = n.issubset(c)  # n是不是c的子
39 print(ret)
40 ret1 = c.issubset(n)  # c是不是n的子
41 print(ret1)
42 ret2 = n.issuperset(c) # n是不是c的父
43 print(ret2)
44 
45 
46 # pop discard remove 三个删除的区别
47 
48 #pop 删除同时可以获取到该值
49 ret = n.pop() #由于集合是无序的,所以pop删除也是无序的
50 print(ret)
51 # discard 删除集合元素,如果元素不存在 返回False 不报错
52 n.discard(11)
53 print(n)
54 #remove 删除集合元素 如果元素不存在 报错
55 #n.remove(99)
56 
57 z = {11,22,33}
58 p = {44}
59 
60 z.intersection(p)  #取交集并更新到z中
61 print(z)
View Code

练习

 1 !/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 # s1=set() #创建空的set集合
 4 # s2={11,22,33,44,55}  #直接创建set集合
 5 # print(s2)
 6 # l1=[11,22,33,44,22,11]
 7 # l2=(11,22,11,22,333)
 8 # l3="123"
 9 # s3=set([11,22,33,22]) #传送可迭代的对象,转换成set集合
10 # s4=set(l3)
11 # print(set(l2))
12 
13 se={11,22,33,55}
14 print(se)
15 se.add(44) #添加
16 print(se)
17 se.clear() #清除所有元素
18 print(se)
19 be={11,22,33}
20 ce={22,55}
21 print(be.difference(ce))#找be中存在。ce中不存在的set集合,返回值
22 print(ce.difference(be))#找ce中存在,be中不存在的set集合,返回值
23 be.difference_update(ce)#找be中存在,ce中不存在的,更新自己
24 print(be)
25 ae={11,22,33,444,555}
26 ae.discard(444) #移除元素,如果没有的话不报错
27 ae.remove(555)#移除元素,没有的话报错
28 print(ae)
29 ee={11,22,33,555}
30 fe={22,555,666,7,7665}
31 print(ee.intersection(fe)) #取A和B的交集,返回新值。原来的A和B不变,取交集,新创建一个set
32 ee.intersection_update(fe) #A和B的交集,不返回值,直接更新自己成这个交集,取交集,修改原来set
33 print(ee)
34 je={11,212,33,515}
35 ke={22,555,666,7,7665}
36 print(je.isdisjoint(ke))#判断A和B有没有交集,有交集返回False,么有交集返回True
37 me={11,212,33,515}
38 ne={11,33}
39 print(ne.issubset(me))#判读A是否是B的子序列。是否是子集
40 print(me.issuperset(ne))#判读A是否是B的父序列。是否是父集
41 oe={11,212,33,55}
42 print(oe.pop()) #随机取一个值,去掉,并且可以返回这个值
43 print(oe)
44 pe={11,22,33,555}
45 qe={22,555,666,7,7665}
46 print(pe.difference(qe))
47 print(qe.difference(pe))
48 print(pe.symmetric_difference(qe))#将不共有的元素,组成一个set集合,差集,创建新对象
49 pe.symmetric_difference_update(qe)#将不共有的元素,组成一个set集合,并更新原有集合,差集,改变原来
50 print(pe)
51 re={11,22,33,555}
52 se={22,555,666,7,7665}
53 print(re.union(se))#A和B合并到一起,并集
54 me={22,555,666,545422}
55 me.update([22,9,8])#更新,多个元素,集合、元组,set
56 print(me)
View Code

2、三目运算符

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

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

3、深浅拷贝

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

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

 

 1 import copy
 2 # ######### 数字、字符串 #########
 3 n1 = 123
 4 # n1 = "i am alex age 10"
 5 print(id(n1))
 6 # ## 赋值 ##
 7 n2 = n1
 8 print(id(n2))
 9 # ## 浅拷贝 ##
10 n2 = copy.copy(n1)
11 print(id(n2))
12   
13 # ## 深拷贝 ##
14 n3 = copy.deepcopy(n1)
15 print(id(n3))

2、其他基本数据类型

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

1、赋值

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

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

2、浅拷贝

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

1 import copy
2   
3 n1 = {"k1": "wu", "k2": 123, "k3": ["alex", 456]}
4   
5 n3 = copy.copy(n1)

3、深拷贝

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

1 import copy
2   
3 n1 = {"k1": "wu", "k2": 123, "k3": ["alex", 456]}
4   
5 n4 = copy.deepcopy(n1)

 4、函数

 1、背景

1、面向过程编程
即:根据业务逻辑从上到下实现功能,其往往用一长段代码来实现指定功能,开发过程中最常见的操作就是粘贴复制,也就是将之前实现的代码块复制到现需功能处。
2、函数式编程
将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可
3、面向对象
对函数进行分类和封装,让开发“更快更好更强...”
 
函数式编程最重要的是增强代码的重用性和可读性
 
2、定义和使用
1 def 函数名(参数):
2        
3     ...
4     函数体
5     ...
6     返回值
函数的定义主要有如下要点:
  • def:表示函数的关键字
  • 函数名:函数的名称,日后根据函数名调用函数
  • 函数体:函数中进行一系列的逻辑计算,如:发送邮件、计算出 [11,22,38,888,2]中的最大数等...
  • 参数:为函数体提供数据
  • 返回值:当函数执行完毕后,可以给调用者返回数据。
    • 1、return xxx None
    • 2、一旦遇到return,函数内部的return一下不执行

 2.1 返回值

函数是一个功能块,该功能到底执行成功与否,需要通过返回值来告知调用者。
以上要点中,比较重要有参数和返回值:
 1 def 发送短信():
 2        
 3     发送短信的代码...
 4    
 5     if 发送成功:
 6         return True
 7     else:
 8         return False
 9    
10    
11 while True:
12        
13     # 每次执行发送短信函数,都会将返回值自动赋值给result
14     # 之后,可以根据result来写日志,或重发等操作
15    
16     result = 发送短信()
17     if result == False:
18         记录日志,短信发送失败...
2.2 、参数
为什么要有参数?
1、形参、实参
2、数量要一直,一一对应
3、指定参数
fun1(p="xxx",q="xxxx")
4、默认参数
默认参数可传可不传,可以覆盖
放在参数的尾部
5、动态参数
*args
**kwargs
6、万能参数
 
 
 普通参数
1 # ######### 定义函数 ######### 
2 
3 # name 叫做函数func的形式参数,简称:形参
4 def func(name):
5     print name
6 
7 # ######### 执行函数 ######### 
8 #  'wupeiqi' 叫做函数func的实际参数,简称:实参
9 func('wupeiqi')
普通参数

默认参数

 1 def func(name, age = 18):
 2     
 3     print "%s:%s" %(name,age)
 4 
 5 # 指定参数
 6 func('wupeiqi', 19)
 7 # 使用默认参数
 8 func('alex')
 9 
10 注:默认参数需要放在参数列表最后
默认参数

动态参数1

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

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

 1 #!/usr/bin/env python
 2 # _*_ coding:utf-8 _*_
 3 
 4 a=[1,3,4]
 5 def fuc(*args):
 6     #print(args)
 7     return args
 8 ret=fuc(a)
 9 print(ret)
10 
11 结果:
12 C:\Python35\python3.exe E:/py_test/s4/s5.py
13 ([1, 3, 4],)
14 
15 
16 
17 #!/usr/bin/env python
18 # _*_ coding:utf-8 _*_
19 
20 a=[1,3,4]
21 def fuc(*args):
22     #print(args)
23     return args
24 ret=fuc(*a)
25 print(ret)
26 C:\Python35\python3.exe E:/py_test/s4/s5.py
27 (1, 3, 4)

动态参数2

 1 def func(**kwargs):
 2 
 3     print args
 4 
 5 
 6 # 执行方式一
 7 func(name='wupeiqi',age=18)
 8 
 9 # 执行方式二
10 li = {'name':'wupeiqi', age:18, 'gender':'male'}
11 func(**li)
12 
13 动态参数2 :**kwargs
14 
15 **kwargs   意指可以传入多个元素以key= value  key的格式是按照变量名的命名规范为标准的
动态参数2

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

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

动态参数3

1 def func(*args, **kwargs):
2 
3     print args
4     print kwargs
5 
6 万能参数
动态参数3
 1 #!/usr/bin/env python
 2 # _*_ coding:utf-8 _*_
 3 a={"k1":2,"k2":3}
 4 b=[1,2,3]
 5 def fuc(*args,**kwargs):
 6     #print(args)
 7     return args,kwargs
 8 ret=fuc(*b,**a)
 9 print(ret)
10 
11 
12 C:\Python35\python3.exe E:/py_test/s4/s5.py
13 ((1, 2, 3), {'k2': 3, 'k1': 2})

扩展:发送邮件实例

 1 #!/usr/bin/env python
 2 # _*_ coding:utf-8 _*_
 3 __author__ = 'liujianzuo'
 4 
 5 
 6 def email(p,text,subject):
 7     import smtplib
 8     from email.mime.text import MIMEText
 9     from email.utils import formataddr
10 
11     ret = True
12     try:
13 
14         msg = MIMEText(text, 'plain', 'utf-8')
15         msg['From'] = formataddr(["武沛齐",'wptawy@126.com'])
16         msg['To'] = formataddr(["走人",'424662508@qq.com'])
17         msg['Subject'] = subject
18 
19         server = smtplib.SMTP("smtp.126.com", 25)
20         server.login("wptawy@126.com", "WW.3945.59")
21         server.sendmail('wptawy@126.com', [p,], msg.as_string())
22         server.quit()
23     except:
24         ret = False
25     return ret
26 
27 
28 r1=email("1223995142@qq.com","python test email +===","subject==pyhon")
29 if r1:
30     print("发生成功")
31 else:
32     print("发送失败")
View Code

3、全局变量、局部变量

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

 

 1 #全局变量一般以大写命名,局部变量以小写命名
 2 #全局变量
 3 p=234
 4 def f1():
 5     #局部变量
 6     a=123
 7     p=999 #全局变量在内部被修改。只在内部起作用
 8     global p #应用到全局变量。
 9     print(p)
10     print(a)
11 def f2():
12     #局部变量
13     a=456
14     print(p)
15     print(a)
16 f1()
17 f2()
18  output:
      999
      123
      999

      456

19 总结 20 全局变量: 21 大写 22 修改,global 23 局部变量: 24 小写,仅仅在代码块中能用

 

 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:
31

 

函数的嵌套定义

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、简述普通参数、指定参数、默认参数、动态参数的区别

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

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

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 st=raw_input("str:")
 5 def count_str(a):
 6     sz=zm=kg=qt=0
 7     # temp=str(a)
 8     for i in a:
 9         # print i
10         if i.isdigit():
11             sz+=1
12         elif i.isalpha():
13             zm+=1
14         elif i.isspace():
15             kg+=1
16         else:
17             qt+=1
18     return (sz,zm,kg,qt)
19 jg=count_str(st)
20 print jg

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

 1 def obj_len(args):
 2     if isinstance(args,str) or isinstance(args,list) or isinstance(args,tuple):
 3         if len(args)>5:
 4             return True
 5         else:
 6             return False
 7     else:
 8         return None
 9 st="jkljkjlj"
10 lis=[11,22,33,44,55]
11 tup=(11,22,33,44,55,66)
12 print obj_len(st),obj_len(lis),obj_len(tup)

 

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

 1 def has_space(args):
 2     if isinstance(args,str) or isinstance(args,list) or isinstance(args,tuple):
 3         for i in args:
 4             if i == " ":
 5                 return True
 6                 break
 7         else:
 8             return False
 9     else:
10         return None
11 st="jkljkjlj"
12 lis=[11,22,33,44,55," "]
13 tup=(11,22,33,44,55,66," ")
14 print has_space(st),has_space(lis),has_space(tup)

 

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

 1 # def fun(args):
 2 #     if len(args)>2:
 3 #             ret=args[0:2]
 4 #             return ret
 5 #     else:
 6 #         return args
 7 #     # return args 也可以不写else直接这样写
 8 # inp=[11,22,33,44,55]
 9 # print fun(inp)
10 
11 --------------------
12 def fun2(args):
13     if len(args)>2:
14         del args[2:]
15 li=[11,22,33,444,55]
16 fun2(li)
17 print li

 

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

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

 

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

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

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

 

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

 

posted @ 2017-02-18 09:32  崔崔0624  阅读(276)  评论(0编辑  收藏  举报
TOP