-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmypr_function.py
408 lines (328 loc) · 8.35 KB
/
mypr_function.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
# 函数的基本概念_内存分析_函数分类_定义和调用
# 函数的定义和调用
def add(a,b,c):
'''文档字符串--完成三个数的加法,并返回值'''
sum = a + b + c
print("{0} {1} {2}三个数的和是:{3}".format(a,b,c,sum))
return sum
print(add) # 是一个函数对象
print(id(add)) # 函数的内存地址
print(type(add)) # 函数的类型
add(1,2,3)
add(10,20,30)
#形参和实参_文档字符串_函数的注释
#形参:定义函数时,小括号中的变量,本质是变量
#实参:调用函数时,传递给函数的数据,本质是值
def print_info(a,b):
'''
实现两个参数的比较,并返回较大的值
:param a: 一个参数
:param b: 一个参数
:return: 返回较大的参数
'''
if a>b:
print("{0}大于{1}".format(a,b))
return a
else:
print("{0}小于{1}".format(a,b))
return b
print(10,90)
print(10,5)
# help(print_info) # 查看函数的文档字符串
print(print_info.__doc__) # 查看函数的文档字符串
def print_star(n):
'''
打印n个星号
:param n:
:return:
'''
s = "*" * n
return s
print(print_star(10))
print(print_star.__doc__)
#返回值详解
def my_avg(a,b):
'''
实现两个数的平均值,并返回
:param a:
:param b:
:return:
'''
return (a+b)/2
a1 = my_avg(10,20) *120 +3
print(a1)
def printShape(n):
'''
打印n行的图形
:param n:
:return:
'''
s1 = "#" *n
s2 = "$" *n
return [s1,s2]
c = printShape(5)
print(type(c))
print(type(printShape(3)))
print(type(printShape))
# 函数也是对象_内存分析
def my_test(n):
print("*"*n)
c = my_test # 函数也是对象--指向的还是同一个函数-内存地址相同
b = c # 函数也是对象
print(id(c))
c(2)
b(3)
# 上述代码就是 两个变量 指向的是--同一个函数对象
print(my_test,"函数对象")
print(id(my_test),"函数内存地址")
print(type(my_test),"函数类型")
zhengshu = int
print(zhengshu(3.14)) # 类型转换
s = str
print(s(3.14)) # 类型转换
# str ='ddd'
# print(str)
# print(str(3.14)) # 报错了--原因是str是一个字符串,不是一个函数
# 变量的作用域_全局变量_局部变量_栈帧内存分析讲解
# a =100
# def f1():
# global a # 声明为全局变量
# a = 4
# b = 3
# print(a+b)
# f1()
# print(a)
# a = 100
# def f1(a,b,c):
# print(a,b,c)
#
# print(locals(),"查看局部变量") # 查看局部变量
# print("$"*2000)
# print(globals(),"查看全局变量") # 查看全局变量
#
# f1(1,2,3)
# 局部变量和全局变量_效率测试
import time
a = 100
def test01():
start = time.time()
global a
for i in range(100000000):
a += 1
end = time.time()
print("test01耗时:{0}".format(end-start))
def test02():
start = time.time()
c=1000
for i in range(100000000):
c += 1
end = time.time()
print("test02耗时:{0}".format(end-start))
test01()
test02()
#参数的传递_传递可变对象_内存分析
#可变对象有:列表、字典、集合、自定义对象、函数对象、模块对象
#不可变对象有:数字、字符串、元组、布尔值、None
b = [10,20]
def f2(m):
print("m=",id(m))
m.append(30)
f2(b)
print("b:",id(b))
print(b)
# 上述代码 --对于可变对象 传递的是引用,对于不可变对象 传递的是值
# 也就是说 m在append的时候 会改变b的值,因为m和b指向的是同一个对象
#参数的传递_传递不可变对象_内存分析
ac = 100
def fc1(n):
print("n=",id(n))
print("n=",id(n))
print(n)
fc1(ac)
print("ac=",id(ac))
# 写 操作
def fc2(n2):
print("n2=",id(n2))
n2+=200 # 由于 n+=200 是一个写操作,所以会开辟新的内存空间 --所以两者不是同一个对象
print("n2=",id(n2))
print(n2)
fc2(ac)
print("ac=",id(ac),ac)
print("*"*100)
print()
#浅拷贝和深拷贝_内存分析
import copy
def testCopy():
'''
浅拷贝
:return:
'''
a = [10,20,[5,6]]
b = copy.copy(a)
print("a=",id(a),"浅拷贝",a)
print("b=",id(b),"浅拷贝",b)
b.append(30)
b[2].append(7)
print("浅拷贝后 修改b的值")
print("a",a)
print("b",b)
def testDeepCopy():
'''
深拷贝
:return:
'''
a = [10,20,[5,6]]
b = copy.deepcopy(a)
print("a=",id(a),"深拷贝",a)
print("b=",id(b),"深拷贝",b)
b.append(30)
b[2].append(7)
print("深拷贝后 修改b的值")
print("a",a)
print("b",b)
testCopy()
print("*"*100)
testDeepCopy()
print("*"*100)
print()
#参数的传递_不可变对象含可变子对象_内存分析
#传递不可变对象时,不可变对象中包含可变对象,那么可变对象的值是可以改变的
a = (10,20,[5,6])
print("a=",id(a))
def f3(m):
'''
传递不可变对象时,不可变对象中包含可变对象,那么可变对象的值是可以改变的
:param m:
:return:
'''
print("m=",id(m))
m[2][0] = 888
print(m)
print("m=",id(m))
f3(a)
print(a) # 由于元组是不可变对象,所以元组的值是不可以改变的,但是元组中的列表是可以改变的
print("*"*100)
print()
#数的类型_位置参数_默认值参数_命名参数
# 位置参数
def f21(a,b,c):
print("a={0},b={1},c={2}".format(a,b,c),"位置参数")
f21(1,2,3)
# 默认值参数
def f22(a,b,c=100):
print("a={0},b={1},c={2}".format(a,b,c),"默认值参数")
f22(3,4)
# 命名参数
def f23(a,b,c):
print("a={0},b={1},c={2}".format(a,b,c),"命名参数")
f23(b=10,c=20,a=30)
print("*"*100)
print()
#参数的类型_可变参数_强制命名参数
# 可变参数 *c 代表可变参数
def f24(a,b,*c):
print("a={0},b={1},c={2}".format(a,b,c),"可变参数")
f24(1,2,3,4,5,6,7,8,9)
# 强制命名参数
def f25(*c,a,b):
print("a={0},b={1},c={2}".format(a,b,c),"强制命名参数")
f25(1,2,3,4,5,6,7,8,9,a=10,b=20)
def f26(a,b,**c):
'''
** 是字典类型
:param a:
:param b:
:param c:
:return:
'''
print("a={0},b={1},c={2}".format(a,b,c),"** 是字典类型")
f26(1,2,x=100,y=200,z=300)
print("*"*100)
print()
# lambda表达式和匿名函数
# lambda表达式的定义 lambda 参数列表:表达式
f = lambda a,b,c:a+b+c
print(f(10,20,30),"f")
g = [lambda a:a*2,lambda b:b*3,lambda c:c*4]
print(g)
print(id(g))
print(type(g))
print(g[0](2),g[1](3),g[2](4),"g")
print("*"*100)
print()
#eval()函数的用法和注入安全隐患问题
s = "print('hello world')"
eval(s)
a = 10
b = 20
c = eval("a+b")
print(c)
dict1 = dict(a=100,b=200)
d1 = eval("a+b")
d = eval("a+b",dict1) # 通过字典传递参数 与d1的值不同的原因是,d1是在全局变量中查找的
print(d,d1)
print("*"*100)
print()
#递归函数_函数调用内存分析_栈帧的创建
def my_resursion(n):
print("start:"+str(n))
if n == 1:
print("resursion over")
else:
my_resursion(n-1)
print("end:"+str(n)) # 递归函数的调用过程是一个栈帧的过程
my_resursion(9)
print("*"*100)
print()
#递归函数_阶乘计算案例
print("阶乘计算案例")
def factorial(n):
if n == 1:
return 1
else:
return n*factorial(n-1)
print(factorial(500))
print("*"*100)
print()
#嵌套函数_内部函数_数据隐藏
def outer():
print("outer running")
def inner():
print("inner running")
inner()
outer()
# inner() # 报错,因为inner是一个局部函数,只能在outer函数中调用
def printName(isChinese,name,familyName):
def inner_print(a,b):
print("{0} {1}".format(a,b))
if isChinese:
inner_print(familyName,name)
else:
inner_print(name,familyName)
printName(True,"小明","张")
printName(False,"Tom","Smith")
# nonlocal和global关键字
a = 100
def outer():
b = 10
def inner():
nonlocal b # nonlocal关键字,用于在局部函数中修改外部函数的局部变量
print("inner b=",b)
b = 20
global a # global关键字,用于在局部函数中修改全局变量
a = 200
inner()
print("outer b=",b)
outer()
print("a=",a)
print("*"*100)
print()
# LEGB规则 -- 作用域的查找顺序--局部变量、外部函数的变量、全局变量、内置变量
s = 'global'
def outer():
# s = "outer"
def inner():
# s = "inner"
print(s)
inner()
outer()