Python 函数

函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。

函数能提高应用的模块性,和代码的重复利用率。你已经知道Python提供了许多内建函数,比如print()。但你也可以自己创建函数,这被叫做用户自定义函数。


定义一个函数

你可以定义一个由自己想要功能的函数,以下是简单的规则:

  • 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号()
  • 任何传入参数和自变量必须放在圆括号中间。圆括号之间可以用于定义参数。
  • 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
  • 函数内容以冒号起始,并且缩进。
  • return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。
def ChangeInt(a):
a = 10
b = 2
ChangeInt(b)
print(b)
def changeme(mylist):
"修改传入的列表"
mylist.append([1, 2, 3, 4])
print("函数内取值: ", mylist)
return # 调用changeme函数
mylist = [10, 20, 30]
changeme(mylist)
print("函数外取值: ", mylist)
def printme(str):
"打印任何传入的字符串"
print(str)
return
# 调用printme函数
printme(str="My string")
# 可写函数说明
def printinfo(name, age):
"打印任何传入的字符串"
print("Name: ", name)
print("Age ", age)
return
# 调用printinfo函数
printinfo(age=50, name="miki");
def printinfo(args,*vartuple):
"打印任何传入的参数"
print(args)
for var in vartuple:
print(var)
return
# 调用printinfo 函数
printinfo(10)
printinfo(70, 60, 50)

实参和形参

#定义函数括号里的一般叫形参
#调用时括号里传递的参数一般叫实参
#比如:
def students(age):
print('my age is %s' % age) students(18) age就是形参,18就是实参

参数的具体应用

'''
1、位置参数:按照从左到右的顺序定义的参数
位置形参:必选参数
位置实参:按照位置给形参传值
'''
def foo(x,y):
print(x,y)
foo(1,2)
#结果:1,2 '''
2、关键字参数:按照key=value的形式定义的实参
无需按照位置为形参传值
注意的问题:
1. 关键字实参必须在位置实参右面
2. 对同一个形参不能重复传值
'''
def foo(x,y):
print(x,y)
foo(y=2,x=1)
结果:1,2
'''
3、默认参数:形参在定义时就已经为其赋值
可以传值也可以不传值,经常需要变得参数定义成位置形参,变化较小的参数定义成默认参数(形参)
注意的问题:
1. 只在定义时赋值一次
2. 默认参数的定义应该在位置形参右面
3. 默认参数通常应该定义成不可变类型
'''
def foo(x,y=2):
print(x,y)
foo(1)
#结果:1,2
foo(1,3)
#结果:1,3 '''
4、可变长参数:
可变长指的是实参值的个数不固定
而实参有按位置和按关键字两种形式定义,针对这两种形式的可变长,形参对应有两种解决方案来完整地存放它们,分别是*argsh和**kwargs
''' #*args:传递的参数会变成元组
def foo(x,y,*args):
print(x,y,args)
foo(1,2,3)
#结果:1 2 (3,)
#**kwargs:传递的参数会变成字典 def foo(x,y,**kwargs):
print(x,y,kwargs)
foo(1,2,a=3,b=4)
#结果:1 2 {'a': 3, 'b': 4}

函数参数的传递

return 语句

return语句[表达式]退出函数,选择性地向调用方返回一个表达式。不带参数值的return语句返回None。之前的例子都没有示范如何返回数值,下例便告诉你怎么做:

# 可写函数说明
def add_sum(arg1, arg2):
# 返回2个参数的和."
total = arg1 + arg2
print("函数内 : ", total)
return total # 调用sum函数
total = add_sum(10, 20)

函数的特性

#函数可以被引用
def f1():
print('this is f1')
return 'ok'
res = f1()
print(res) #函数可以当参数传递
def foo(a):
print(a)
def bar(b):
print(b) bar(foo('你好')) #嵌套函数
def f1():
def f2():
def f3():
print('this is f3')
f3()
f2()
f1()

函数的特性

名称空间和作用域

#内置名称空间:(python启动时就有)python解释器内置的名字,print,max,min

#全局名称空间:(执行python文件时启动)定投定义的变量

#局部名称空间:(调用函数时启动,调用结束失效)函数内部定义的变量

总结:三者的加载顺序
内置--->全局--->局部 三者的访问顺序
局部--->全局--->内置

装饰器

什么是装饰器?
在不修改源代码和调用方式的基础上给其增加新的功能,多个装饰器可以装饰在同一个函数上
import time

def timer(func):
def deco():
start_time = time.time()
res = func()
end_time = time.time()
print('cost', end_time-start_time)
return res
return deco
@timer
def bar():
time.sleep(2)
print('这是bar')
bar()

无参装饰器

import time

def timer(func):
def deco(*args,**kwargs):
start_time = time.time()
res = func(*args,**kwargs)
end_time = time.time()
print('cost', end_time-start_time)
return res
return deco @timer
def bar(a, b):
time.sleep(2)
print('这是bar')
print(a)
print(b)
bar(1,2)

有参装饰器

def default_engine(engine=None):
def auth(func):
def deco(*args, **kwargs):
user = input('user:')
password = input('password:')
if engine == 'mysql':
if user == 'root' and password == 'root':
res = func(*args, **kwargs)
return res
else:
print('用户名或密码错误')
else:
print('没有这个引擎')
return deco
return auth @default_engine(engine='mysql')
def index():
print('welcome to home page') # res = default_engine(engine='mysql')
# index = res(index)
index()

带参数的装饰器

迭代器

 什么是迭代器?

 迭代是一个重复的过程,即每一次重复为一次迭代,并且每次迭代的结果都是下一次迭代的初始值

while True: #只是单纯的重复,因此不是迭代
print('===>') l = [1,2,3]
count=0
while count<len(l): #首先是重复动作,其次上一次的结果是下一次的初始值,因此,是迭代
print(l[count])
count+=1

为什么要有迭代器?什么是可迭代对象?什么是迭代器对象?

#1、为何要有迭代器?
对于序列类型:字符串、列表、元组,我们可以使用索引的方式迭代取出其包含的元素。但对于字典、集合、文件等类型是没有索引的,若还想取出其内部包含的元素,则必须找出一种不依赖于索引的迭代方式,这就是迭代器 #2、什么是可迭代对象?
可迭代对象指的是内置有__iter__方法的对象,即obj.__iter__,如下:
'world'.__iter__
(4,5,6).__iter__
[1,2,3].__iter__
{'a':1}.__iter__
{'a','b'}.__iter__
open('a.txt').__iter__
#3、什么是迭代器对象?
可迭代对象执行obj.__iter__()得到的结果就是迭代器对象
而迭代器对象指的是即内置有__iter__又内置有__next__方法的对象 #4、文件类型是迭代器对象
open('a.txt').__iter__()
open('a.txt').__next__() #5、总结:
迭代器对象一定是可迭代对象,而可迭代对象不一定是迭代器对象

生成器

什么是生成器?

只要函数里有yield关键字,那么函数名()得到的结果就是生成器,并且不会执行函数内部代码

def bar():
l = ['a','b','c']
for i in l:
yield i res = bar()
for i in res:
print(i)

yield用来返回多个值

匿名函数

info = {
'li':2000,
'zhao':35000,
'wu': 25000,
'du': 30000
} #max
print(max(info,key=lambda k: info[k])) #sorted
print(sorted(info,key=lambda k: info[k],reverse=True)) #map
name = ['zhao', 'du', 'wu']
res = map(lambda name: '%s_NB' % name,name)
print(list(res)) #filter
name = ['zhao_NB', 'du_NB', 'wu']
res = filter(lambda name: name.endswith('NB'),name)
print(list(res))

max,sorted,map,filter

多任务

多线程特点:

#线程的并发是利用cpu上下文的切换(是并发,不是并行)
#多线程执行的顺序是无序的
#多线程共享全局变量
#线程是继承在进程里的,没有进程就没有线程
#GIL全局解释器锁
#只要在进行耗时的IO操作的时候,能释放GIL,所以只要在IO密集型的代码里,用多线程就很合适
# 无序的,并发的
def test1(n):
time.sleep(1)
print('task', n) for i in range(10):
t = threading.Thread(target=test1,args=('t-%s' % i,))
t.start()
#计算并发所用的时间
import threading
import time def test1(n):
time.sleep(1)
print('task', n) def test2(n):
time.sleep(1)
print('task', n) start = time.time()
l = []
t1 = threading.Thread(target=test1, args=(1,))
t2 = threading.Thread(target=test1, args=(2,))
t1.start()
t2.start()
l.append(t1)
l.append(t2)
for i in l:
i.join()
end = time.time()
print(end - start)

GIL的全称是:Global Interpreter Lock,意思就是全局解释器锁,这个GIL并不是python的特性,他是只在Cpython解释器里引入的一个概念,而在其他的语言编写的解释器里就没有这个GIL例如:Jython,Pypy

为什么会有gil?:

随着电脑多核cpu的出现核cpu频率的提升,为了充分利用多核处理器,进行多线程的编程方式更为普及,随之而来的困难是线程之间数据的一致性和状态同步,而python也利用了多核,所以也逃不开这个困难,为了解决这个数据不能同步的问题,设计了gil全局解释器锁。

说到gil解释器锁,我们容易想到在多线程中共享全局变量的时候会有线程对全局变量进行的资源竞争,会对全局变量的修改产生不是我们想要的结果,而那个时候我们用到的是python中线程模块里面的互斥锁,哪样的话每次对全局变量进行操作的时候,只有一个线程能够拿到这个全局变量;看下面的代码:

import threading
global_num = 0 def test1():
global global_num
for i in range(1000000):
global_num += 1 print("test1", global_num) def test2():
global global_num
for i in range(1000000):
global_num += 1 print("test2", global_num) t1 = threading.Thread(target=test1)
t2 = threading.Thread(target=test2)
t1.start()
t2.start()
在上面的例子里,我们创建了两个线程来争夺对global_num的加一操作,但是结果并非我们想要的,所以我们在这里加入了互斥锁 import threading
import time
global_num = 0 lock = threading.Lock() def test1():
global global_num
lock.acquire()
for i in range(1000000):
global_num += 1
lock.release()
print("test1", global_num) def test2():
global global_num
lock.acquire()
for i in range(1000000):
global_num += 1
lock.release()
print("test2", global_num) t1 = threading.Thread(target=test1)
t2 = threading.Thread(target=test2)
start_time = time.time() t1.start()
t2.start()

多进程

#一个程序运行起来之后,代码+用到的资源称之为进程,它是操作系统分配资源的基本单位,不仅可以通过线程完成多任务,进程也是可以的
#进程之间是相互独立的
#cpu密集的时候适合用多进程
#进程之间不共享
import multiprocessing
from multiprocessing import Pool
import time
import threading
g_num = 0
def edit():
global g_num
for i in range(10):
g_num += 1 def reader():
print(g_num) if __name__ == '__main__':
p1 = multiprocessing.Process(target=edit)
p2 = multiprocessing.Process(target=reader())
p1.start()
p2.start()
p1.join()
p2.join()

进程之间资源不共享

#多进程并发
import multiprocessing
from multiprocessing import Pool
import time
def test1():
for i in range(10):
time.sleep(1)
print('test', i) def test2():
for i in range(10):
time.sleep(1)
print('test', i) if __name__ == '__main__':
p1 = multiprocessing.Process(target=test1)
p2 = multiprocessing.Process(target=test2)
p1.start()
p2.start()

多进程并发

#进程池
import multiprocessing
from multiprocessing import Pool
import time
import threading
g_num = 0
def test1(n):
for i in range(n):
time.sleep(1)
print('test1', i) def test2(n):
for i in range(n):
time.sleep(1)
print('test2', i)
def test3(n):
for i in range(n):
time.sleep(1)
print('test3', i) def test4(n):
for i in range(n):
time.sleep(1)
print('test4', i) if __name__ == '__main__':
pool = Pool(3)#把进程声明出来括号里不写东西说明无限制,如果写数字,就是最大的进程数
pool.apply_async(test1,(10,))#用pool去调用函数test1,参数为10格式为(10,)
pool.apply_async(test2,(10,))#用pool去调用函数test2,参数为10格式为(10,)
pool.apply_async(test3,(10,))#用pool去调用函数test3,参数为10格式为(10,)
pool.apply_async(test4,(10,))#用pool去调用函数test4,参数为10格式为(10,)
pool.close()#close必须在join的前面
pool.join()

进程池并发

协程并发(gevent)

# 进程是资源分配的单位
# 线程是操作系统调度的单位
# 进程切换需要的资源最大,效率低
# 线程切换需要的资源一般,效率一般
# 协程切换任务资源很小,效率高
# 多进程、多线程根据cpu核数不一样可能是并行的,但是协成在一个线程中
#协程,自动切换
import gevent,time
from gevent import monkey
monkey.patch_all()
def test1():
for i in range(10):
time.sleep(1)
print('test1', 1) def test2():
for i in range(10):
time.sleep(2)
print('test2', 1) g1 = gevent.spawn(test1)
g2 = gevent.spawn(test2)
g1.join()
g2.join()

协程

#server端
import gevent
from gevent import socket, monkey
monkey.patch_all()
def server_recv_conn(port):
s = socket.socket()
s.bind(('0.0.0.0', port))
s.listen(200)
while True:
conn, addr = s.accept()
g = gevent.spawn(recv_request, conn)
g.join()
def recv_request(conn):
while True:
data = conn.recv(1024)
data = data.decode('utf-8')
print("recv:", data)
conn.send(data.upper().encode('utf-8')) if __name__ == '__main__':
server_recv_conn(8888) #client端
import socket HOST = 'localhost'
PORT = 8888
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
while True:
msg = input("==>:")
s.send(msg.encode('utf-8'))
data = s.recv(1024)
print('接收:', data.decode('utf-8'))
s.close()

协程实现socket server高并发

python之函数2的更多相关文章

  1. python的函数

    函数一词起源于数学,但是在编程中的函数和数学中的有很大不同.编程中的函数式组织好的,可重复使用的,用于实现单一功能或相关联功能的代码块. 我们在学习过程中已经使用过一些python内建的函数,如pri ...

  2. python strip()函数 介绍

    python strip()函数 介绍,需要的朋友可以参考一下   函数原型 声明:s为字符串,rm为要删除的字符序列 s.strip(rm)        删除s字符串中开头.结尾处,位于 rm删除 ...

  3. python split()函数

    Python split()函数 函数原型: split([char][, num])默认用空格分割,参数char为分割字符,num为分割次数,即分割成(num+1)个字符串 1.按某一个字符分割. ...

  4. Python数学函数

    1.Python数学函数 1.abs(x):取绝对值,内建函数 2.math.ceil(x):向上取整,在math模块中 3.cmp(x,y):如果 x < y ,返回-1:如果 x == y ...

  5. Python回调函数用法实例详解

    本文实例讲述了Python回调函数用法.分享给大家供大家参考.具体分析如下: 一.百度百科上对回调函数的解释: 回调函数就是一个通过函数指针调用的函数.如果你把函数的指针(地址)作为参数传递给另一个函 ...

  6. Python之函数与变量

    本节内容 函数介绍及其作用 函数的定义与调用 函数的参数说明 全局变量与局部变量 值传递和引用传递 一.函数的介绍及其作用 编程语言中的函数与数学中的函数是有区别的:数学中的函数有参数(输入),就会有 ...

  7. Python基础-函数篇

    本节内容 1. 函数基本语法及特性 2. 参数与局部变量 3. 返回值 嵌套函数 4.递归 5.匿名函数 6.函数式编程介绍 7.高阶函数 8.内置函数  函数与函数式编程 1.面向对象: 华山派-- ...

  8. 【C++实现python字符串函数库】strip、lstrip、rstrip方法

    [C++实现python字符串函数库]strip.lstrip.rstrip方法 这三个方法用于删除字符串首尾处指定的字符,默认删除空白符(包括'\n', '\r', '\t', ' '). s.st ...

  9. 【C++实现python字符串函数库】二:字符串匹配函数startswith与endswith

    [C++实现python字符串函数库]字符串匹配函数startswith与endswith 这两个函数用于匹配字符串的开头或末尾,判断是否包含另一个字符串,它们返回bool值.startswith() ...

  10. 【C++实现python字符串函数库】一:分割函数:split、rsplit

    [C++实现python字符串函数库]split()与rsplit()方法 前言 本系列文章将介绍python提供的字符串函数,并尝试使用C++来实现这些函数.这些C++函数在这里做单独的分析,最后我 ...

随机推荐

  1. ES6 中 let and const

    let 和 const 命令 let 命令 基本用法 ES6 新增了let命令,用来声明变量.它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效. { let a = 10; v ...

  2. 写一个简单的C词法分析器

    写一个简单的C词法分析器 在写本文过程中,我参考了<词法分析器的实现>中的一些内容.这里我们主要讨论写一个C语言的词法分析器. 一.关键字 首先,C语言中关键字有: auto.break. ...

  3. px转rem

    第一步: 第二步:html引入js 第三步:转换单位,100px=0.1rem

  4. mysqli_query数据库有数据,查不出来

    MySQLDB.class.php <?php /** * 数据库操作工具类 */ class MySQLDB { // 定义相关属性 private $host;// 主机地址 private ...

  5. Servlet会话管理一(URL重写和表单隐藏域)

    会话可以简单的理解为客户端用户打开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器的整个过程称为一个会话.即一个客户端用户和服务器端进行通讯的过程,也是客户端和服务器端之间的数据传 ...

  6. PhpStorm 不停地 updating indices

    问题描述: 环境:PhpStorm 框架: Laravel 5.0, php artisan make:test bar.foo 之后,PhpStorm 一直不停地 Updating indices ...

  7. SSRF-php初探

    0x00 前言 1)    SSRF的概念很好理解,请自行百度. 2)    JAVA/PHP/PYTHON都存在SSRF漏洞(至于其他语言的情况,了解粗浅尚不得知). 3)    SSRF的利用方式 ...

  8. 【转】 vxWorks下常用的几种延时方法

    在应用编程的时候,通常会碰到需要一个任务在特定的延时之后执行一个指定的动作,如等待外设以确保数据可靠,控制扬声器发声时间以及串口通信超时重发等.这就需要利用定时器机制来计量特定长度的时间段. vxWo ...

  9. 【Web】Nginx配置规则

    Nginx配置基本说明 以下是nginx的基本配置文件如下(编辑命令:vi /usr/local/nginx/conf/nginx.conf): #user nobody; #nginx进程数,建议设 ...

  10. js-day02

    1.数据类型转换2.函数3.分支结构*******************************1.数据类型转换 数据类型:number,string,boolean,null,undefined ...