python基础编程: 函数示例、装饰器、模块、内置函数

目录:

  1. 函数示例
  2. 装饰器
  3. 模块
  4. 内置函数

一、函数示例:

  1、为什么使用函数之模块化程序设计:

    不使用模块程序设计的缺点:
    1、体系结构不清晰,可主读性差;
    2、可扩展性差;
    3、程序冗长;

  2、定义函数:
    def fun(args):
      '描述信息'
      函数体
    return 返回值

  定义函数的三种形式:
    无参函数

1
2
3
4
def foo():
    print('in the foo')
 
foo() 

有参函数:

1
2
3
4
def bar(x,y):
    print('in the bar')
 
bar(1,2)

空函数:

1
2
def func():
    pass

空函数的应用示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def put():
    pass
 
def get():
    pass
 
def cd():
    pass
 
def ls():
    pass
 
def auth():
    pass

3、调用函数:
三种形式:
语句形式:

1
2
3
4
def foo():
    print('in the foo')
 
foo()

表达式形式:

1
2
3
4
5
6
7
8
def my_max(x,y)
    if x>y:
        return x
    else:
        return y
 
res = my_max(1,2)
res = 10 * my_max(1,2)   <br>作为另外一个函数的参数:<br>my_max(1,my_max(2,3)): #先比较2与3的最大值,再与1作比较; <em id="__mceDel" style="background-color: rgba(255, 255, 255, 1); font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px">   </em>

4、函数的返回值三种形式:
不返回函数:

1
2
3
4
5
def foo():
    print('in the foo')
 
res = foo()
print(res)

返回一个函数:

1
2
3
4
def foo():
    return 1
res = foo()
print(res)

返回多个:

1
2
3
4
5
def foo():
    return 1,'s',[1,2,3]
 
res = foo()
print(res)

5、函数的参数:

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
def func(x,y): #形参在调用时才真正占用内存空间,调用结束则释放内存空间;
    print(x)
    print(y)
 
fund(1,2) #实参真实占用内存空间;
 
 
def func(x,y):
    if type(x) is int and type(y) is int:
    return x+y
 
func(1,'a')
 
def func(x,y): #使用文档注释来提醒用户输入参数类型;
    '''
    '''
    return x+y
 
func(1,'a')
 
 
def func(x:int,y:int)->int: #只是一个提示作用;
    pass
    print(func.__annotations__)
 
从实参的角度,
按位置传值:
def foo(x,y):
    print(x,y)
foo(1,2)
 
按关键字传参:key = value
def foo(x,y):
    print(x,y)
foo(y=2,x=1) #优点:不用按位置来输入参数;
 
针对同一个形参,要么按照位置要么按照关键字为形参传值;关键字参数必须写到位置参数的右边;
如:foo(1,x=1,y=2) 此方法会报错;
 
从形参的角度:位置参数,默认参数,可变长参数*args;**kwargs;
按位置定义的形参:
def foo(x,y,z): #位置参数;也就是必传值参数;
    print(x)
    print(y)
    print(z)
 
foo(1,2,3)
foo(y=2,x=1,z=3)
 
按默认参数的形参:
def foo(x,y=1): #y就是默认参数;但也可以去赋值;默认参数建议不要使用列表或字典等可变类型;必须放在默认参数之后;
    print(x)
    print(y)
foo(1)
 
按可变长参数的形参:
def foo(x,y=1,*args): #可变长参数必须放在位置参数与默认参数的后面;此情况一般不使用位置参数;
    print(x)
    print(y)
    print(args)
 
foo(1,2,3,4,54,6,3,y=2) #错
foo(1,2,3,4,54,y=2,3,5) #错
foo(1,2,3,4,54,6,3) #对
 
 
def foo(x,y,*args):
    print(x)
    print(y)
    print(*args)
 
l=['a','b']
foo(1,2,*1) #*args的形式就等于1,2,3,4,5 解包;
 
('a','b')
 
  
 
def foo(x,y,z):
    print(x)
    print(y)
    print(z)
 
# foo(1,2,3)
l=[1,2,3]
foo(*l)
 
 
def foo(x,**kwargs):
    print(x)
    print(kwargs)
 
foo(1,y=3,z=2)
dic = {'a':1,'b':2}
foo(1,**dic) #foo(1,a=1,b=2)
 
def foo(x,y,z):
    print(x,y,z)
 
foo(**{'a':1,'b':2,'c':3}) #foo(a=1,b=2,c=3),要把a,b,c改成x,y,z
foo(**{'x':1,'y':2,'z':3})
 
注:位置参数 -> 默认参数,*args, **kwargs
1*args 相当于展开按照位置的方式去写;
2**kwargs 相当于把kwargs按照关键字的方式去写;

6、函数是第一类对象的意思就是函数可以被当作数据来传递;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def func()
    print('in the fun')
 
fl = fun
fl()
 
函数可作为参数:高阶函数:
def foo(x):
    x()
foo(func)
 
返回值可以是函数:
##########################################
 
可以作为容器类型的元素:
func_dic={
    'func':func
}
 
func_diuc['func']()

7、函数的嵌套:分为两种:

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
嵌套的调用:
def my_max1(a,b,c,d):
    res1=my_max(a,b)
    res2=my_max(res1,c)
    res3=my_max(res2,d)
    return res3
 
def my_max(x,y):
    if x > y:
        return x
    else:
        return y
 
print(my_max1(100,2,-1,5))
嵌套的定义: python支持静态的嵌套域;
x=1
def f1():
    def f2():
        print(x)
#def f3():
#   print(x)
#return f3 
    return f2
 
f2=f1()
 
闭包函数:
def f1():
    x=1
    def f2():
        print(x)
    return f2
 
f = f1()
f()
 
示例:
from urllib request import urlopen #用来爬网页;
def page(url):
    def get():
        return urlopen(url).read()
    return get
 
baidu = page('http//ww.baidu.com')
python = page('http://www.python.org')
baidu()

二、装饰器

装饰器:在遵循下面的两个原则 的前提下为被修饰者添加新功能;
函数功能的扩展原则:
1、一定不能修改源代码;
2、不能改变函数的调用方式;

装饰器本身是一个函数,被装饰的也是一个函数;

示例:

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
def index():
print('in the ndex')
index()
 
@timer #表示方法:index = timer(index)
def index():
print('in the ndex')
index()
 
装饰器的叠加:
@deco3
@deco2
@deco1 #func1 = deco1(index) --> func2=deco2(func1) --> index= deco3(func2)====>index=deco3(deco2(deco1(index)))
def index():
print('in the ndex')
index()
 
示例:
from urllib request import urlopen #用来爬网页;
import time
def timer(func):
def wrapper():
print('in the wrapper-->start')
start_time=time.time()
func()
print('in the wrapper-->stop')
return wrapper
 
@timer #表示方法:index = timer(index)
def index():
print('in the ndex')
index()
 
  
 
from urllib request import urlopen #用来爬网页;
import time
def timer(func):
    def wrapper(*args,**kwargs): #一定不要写死;
        print('in the wrapper-->start')
        start_time=time.time()
        res=func(*args,**kwargs) #home('tom',msg='xxxx')-->home(user,msg) *与位置等同
        func(msg) #运行最原始的index -> index(msg)
        print('in the wrapper-->stop')
        return res
        return wrapper
 
@timer #表示方法:index = timer(index)
def index(msg):
    print('in the ndex',msg)
 
@timer
def home(user,msg):
    print('in the home %s %s',%(user,msg)
    return 1 #返回值要写在wrapper中
 
 
index('hello world')
home('tom',msg='xxxx')

三、模块

 

什么是模块:
模块就是一个包含了python定义和声明的文件;文件名就是模块名字加上.py的后缀;

 

模块只会被导入一次,第一次会导入到内存中,第二次再导入直接去内存调用

 

模块的导入:
第一次导入模块三个事件:
1、创建新的作用域;
2、在该作用域内执行顶级代码;
3、得到一个模块名,绑定到该模块内的代码;

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
为模块起别名:
import spam as sm
    print(sm.money)
from spam import read1 as rea
 
 
导入多个模块:
import ms,spam,re
from spam import (read1,change)可写入多行;
 
 
导入模块的另外一种形式:
from .. import ..
from spam import read1
read1()

 

总结:
从那来就从哪执行,与调用的位置无关;

 

1
2
3
将module中所有非下划线开头的名称导入:
from module import *
__all__ = ['money','read1']

 

注:
模块不支持重载;要加载需要重启程序;

 

1
2
3
4
5
6
7
8
9
10
把文件当做和脚本执行__name__等于'__main__'
print(__name__)
把spam.py文件当作模块去使用__name__等于'spam'
 
 
if __name__ = '__main__':
    print('文件被当作脚本执行时触发的代码')
 
 
可以控制python代码在不同场景下运行的代码;

模块路径的查找:
import sys
sys.path
路径的查找先找内置的路径,再找其他的路径;
来源:
1、当前目录;
2、python path
3、安装时依赖的一些目录;

 

sys.path.append(r'/test') #当前目录有效;
r表示对特殊字符的转义;
sys.path.insert(0,r'/test') #从0的位置插入;

 

导入模块时,先从内建中找相同的模块名,找不到就去sys.path中找;

 

dir()
不会列举出内建模块的名字;
import builtins
dir(builtins)

 


包:
包是一种通过使用‘.模块名’来组织python模块名称空间的方式。

 

无论是import形式还是from...import形式,凡是在导入语句中(而不是在使用时)遇到带点的,都要第一时间提高警觉:这是关于包才有的导入语法

 

包的本质就是一个包含__init__.py文件的目录。

 

from ... import ...

 

需要注意的是from后import导入的模块,必须是明确的一个不能带点,否则会有语法错误,如:from a import b.c是错误语法

 

__init__.py文件

 

不管是哪种方式,只要是第一次导入包或者是包的任何其他部分,都会依次执行包下的__init__.py文件(我们可以在每个包的文件内都打印一行内容来验证一下),这个文件可以为空,但是也可以存放一些初始化包的代码。

 


from glance.api import *

 

在讲模块时,我们已经讨论过了从一个模块内导入所有*,此处我们研究从一个包导入所有*。

 

1
2
3
4
5
6
7
8
9
此处是想从包api中导入所有,实际上该语句只会导入包api下__init__.py文件中定义的名字,我们可以在这个文件中定义__all___:
 
 #在__init__.py中定义
 x=10
 
 def func():
     print('from api.__init.py')
  
 __all__=['x','func','policy']

此时我们在于glance同级的文件中执行from glance.api import *就导入__all__中的内容(versions仍然不能导入)。

 

示例:

1
2
3
4
5
6
7
8
9
10
from glance.api import *
只会运行api下的__init__.py文件;
 
 
在api\__init__.py中输入:
__all__ = ['policy','versions']
 
 
 
import只能导入内建与第三方的模块,否则会出错;

四、内置函数

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
内置函数解释:
 
# !/usr/bin/env python
# -*- coding:utf-8 -*-
 
#返回数字的绝对值。 参数可以是整数或浮点数。 如果参数是复数,则返回其大小。
print(abs(-1.11))
 
#传入一个可被循环的元素,如果这个元素中有一个为False则都为假
# 0 空值 False 都为假
print(all([1,2,3]))
 
#与all相反,只有一个为真,则为真;
print(any([0,2,False]))
 
#这个函数跟repr()函数一样,返回一个可打印的对象字符串方式表示。当遇到非ASCII码时
#就会输出\x,\u或\U等字符来表示。与Python 2版本里的repr()是等效的函数。
print(ascii("dsads"),ascii(66),ascii('b\23'))
 
#将十进制转换为二进制;
print(bin(10))
 
#返回布尔值,即True或False之一,如果参数为false或省略,则返回False; 否则返回True。
print(bool(1))
 
#根据传入的参数创建一个新的字节数组
#如果传入字符串必须给出编码
print(bytearray('你好','utf-8'))
#当source参数是一个可迭代对象,那么这个对象中的元素必须符合大于0 小于256
print(bytearray([256,1,2]))
 
#返回一个的“bytes”对象,返回bytes类型
bytes('中文','utf-8')
 
#检查对象是否可以被调用
def func():
    pass
print(callable(func))
 
#返回整数所对应的Unicode字符,chr(97)返回字符串'a',而chr(8364)返回字符串'€'。
print(chr(126))
 
#是用来指定一个类的方法为类方法,类方法可以不实例化直接调用
class A:
    @classmethod
    def B(cls,arg1,):
        print(arg1)
A.B(1)
A().B(1)
 
#将源编译为代码或者AST对象。代码对象能够通过exec语句来执行或者eval()进行求值。
#源可以是正常字符串,字节字符串或AST对象。
expr = "5+5-1"
obj = compile(expr,"","eval")
print(eval(obj))
 
#返回值为real + imag * j的复数或者转化一个字符串或数为复数。如果第一个参数为字符串,则不需要指定第二个参数。
print(complex(1, 2))
print(complex(1))
print(complex("1+2j"))
 
 
 
# 参数是一个对象和一个字符串。 该字符串必须是对象属性之一的名称。
class A:
    def a1(self):
        print("a1")
    def a2(self):
        print("a2")
 
obj = A
print(dir(obj))
delattr(obj, "a1")
print(dir(obj))
 
#dir 返回对象中的方法
strs="aaa"
print(dir(strs))
 
#返回两个数值的商和余数
print(divmod(7,3))
 
#用于遍历序列中的元素以及它们的下标
print(enumerate([1,2,3]))#返回的是可迭代的对象
for i,j in enumerate(('A','B','C')):
    print(i,j)
 
#将字符串str当成有效的表达式来求值并返回计算结果。
print(eval("1+2+3"))
print(eval("False or True"))
 
#字符串str当成动态语句块执行并返回结果
exec('a=1+2+3')
print(a)
 
#使用指定方法(方法,函数),过滤可迭代对象的元素
def add(arg):
    return arg > 3
 
for i in filter(add,[1,2,3,4,5]):
    print(i)
 
#浮点型
print(float(11))
 
#格式化显示 更多方法请参考官方说明
print('{:,.2f}'.format(111111))
 
#根据传入的参数创建一个新的不可变集合
a = frozenset([1,2,3,4,5])
print(a)
 
#获取对象的属性值
class A():
    def __init__(self,):
        self.name = "123"
b = A()
print(getattr(b,'name'))
 
#返回当前作用域内的全局变量和其值组成的字典
print(globals())
 
#检查对象是否含有属性
class A():
    def __init__(self,):
        self.name = "123"
b = A()
print(hasattr(b,'name'))
 
#哈希值计算
#在当前环境中是唯一的
print(hash('Hello'))
 
#help帮助
def funcs(args):
    """
    Function description
    :param args: args = list
    :return:
    """
    pass
print(help(funcs))
 
#转换16进制
print(hex(44))
 
#显示对象的标识符
print(id("123"))
 
#input标准输入
s = input("user name:")
print(s)
 
#int返回整数
print(int(1.2))
print(int("2"))
 
#判断对象是否是类或者类型元组中任意类元素的实例
print(isinstance("1",int))
print(isinstance(1.1,(int,float)))
 
 
#判断类是否是另外一个类或者类型元组中任意类元素的子类
print(dir(str))
print(issubclass(bytearray,str))
print(issubclass(bool,int))
 
#根据传入的参数创建一个新的可迭代对象
a = iter('12345')
print(next(a))
print(next(a))
 
#返回对象的长度len
a = [1,2,3,4]
 
#转换列表
print(list("abcd"))
 
#返回当前作用域内的局部变量和其值组成的字典
def A():
    print(locals())
    s = 1
    print(locals())
A()
 
#使用指定方法去作用传入的每个可迭代对象的元素,生成新的可迭代对象
def add(x):
    return x+100
lists = [1,2,3,4]
for i in map(add,lists):
    print(i)
 
#max:返回最大值
print(max(1,2,3))
print(max([1,2,3,4]))
 
#在进行切片并赋值数据时,不需要重新copy原列表数据,可以直接映射原数据内存;
s = memoryview(b'abcd')
print(s[1])
 
#返回最小值
print(min(1,2,3))
print(min([2,3]))
 
#返回可迭代对象中的下一个元素值
a = iter('1234')
print(next(a))
 
#创建一个新的object对象(新式类)
class B(object):
    pass
 
#转化成8进制数字符串
print(oct(10))
 
#open文件操作
file = open('test.txt',encoding="utf-8")
 
#ord:返回Unicode字符对应的整数
print(ord("A"))
 
#幂运算
 
print(pow(2,3))
 
#标准输出
print()
 
#property:标示属性的装饰器
#类中使用具体方法请百度,或者等待后续更新
property
 
#range:根据传入的参数创建一个新的range对象
range(10)
range(1,10)
 
"""repr()函数得到的字符串通常可以用来重新获得该对象,repr()的输入对python比较友好。
通常情况下obj==eval(repr(obj))这个等式是成立的。"""
obj='Python'
print(eval(repr(obj)))
 
 
#翻转序列
a = reversed([1,2,3,4,5])
print(list(a))
 
#round:对浮点数进行四舍五入求值
print(round(1.5))
 
#set 转换成集合
print(set([1,2,3]))
 
#setattr:设置对象的属性值
class A():
    def __init__(self,age):
        self.age = age
s = A(11)
print(s.age)
setattr(s,'age',22)
print(s.age)
 
#根据传入的参数创建一个新的切片对象
c1 = slice(3)
c2 = slice(2,4)
c3 = slice(0,5,2)
s = [1,2,3,4,5,6]
print(s[c1])
print(s[c2])
print(s[c3])
 
 
#排序,返回一个新的列表默认按字符ascii码排序
a = [4,3,2,1,7]
print(sorted(a))
 
#标示方法为静态方法的装饰器
class B(object):
    def __init__(self,age):
        self.age = age
 
    @staticmethod
    def hello(args):
        print(args)
 
B.hello("Hello World")
 
#字符串类型
print(str(123))
 
#求和
print(sum([1,2,3,4]))
 
#根据传入的参数创建一个新的子类和父类关系的代理对象
class A(object):
    def __init__(self):
        print("我是 A Clase")
 
class B(A):
    def __init__(self):
        print("我是 B Class")
        super().__init__()
b = B()
 
#元祖
tuple([1,2,3,4])
 
 
#type 返回对象的类型
print(type([1]))
print(type("1"))
 
#返回当前作用域内的局部变量和其值组成的字典,或者返回对象的属性列表
def func():
    print(vars())
    s = 1
    print(vars())
func()
 
#聚合传入的每个迭代器中相同位置的元素,返回一个新的元组类型迭代器
list1 = [1,2,3]
list2 = ["A","B","C","D"]
print(zip(list1,list2))
for i in zip(list1,list2):
    print(i)
 
#__import__:动态导入模块
__import__

  

  

 

posted @   hsggj  阅读(823)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· .NET Core 中如何实现缓存的预热?
· 三行代码完成国际化适配,妙~啊~
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
点击右上角即可分享
微信分享提示