9159金沙游艺场

图片 73
【转】Python爬虫(6)_scrapy框架
图片 4
vue的Virtual Dom实现snabbdom解密

Python之函数总结

一、函数

  我们可以用一段代码来实现我们需要的功能,但是当我们需要重复使用这段代码时,复制粘贴并不是一个酷的方法,我们可以用到函数来实现这一需求

1、为什么要用函数

一、函数定义

    a、避免代码重用

函数是逻辑结构化和过程化的一种编程方法,通过一个函数名封装好一串用来完成某一特定功能的代码

    b、提高代码的可读性

函数的定义:

2、函数的调用

def 函数名(参数1,参数2….):

   返回值=函数名(参数1,参数2)

  ”注释”

   函数定义—返回值

  函数体 

   关键字:return

def func1():  #定义函数
    print('this is a function')  #函数体
func1()  #调用函数

#通常无参函数不需要返回值,有参函数需要有返回值
def func1(name):  #带参数的形式
    print('%s is a good man'%name)
func1('egon')

#关于函数的返回值,如果没有指定,默认是None
#函数与过程的定义就是过程没有返回值,用完之后就没有了,而函数有返回值
def func1(name):
    print('%s is a good man'%name)
print(func1('egon')) 

3、return的作用:

–>  egon is a good man

    a、结束函数的执行

    None

    b、返回要返回的值

函数的优点:1.代码重用

4、返回值的两种情况

      2.保持一致性,易于维护

    a、返回值为None

      3.可扩展性好

图片 1图片 2

注意:1.函数必须先定义,在使用,和变量类似,在定义前使用会报错

def mylen():
    """计算s1的长度"""
    s1 = "hello world"
    length = 0
    for i in s1:
        length = length+1
    print(length)


str_len = mylen()
print(str_len)

   2.函数在定义阶段只检测语法错误,不会执行代码,所以即使在函数体内有未定义的变量名,在函数未调用前也不会报错

不写return

   3.函数的返回值可以是任意类型,如果是返回多个值,一定是元组形式

图片 3图片 4

   4.return
的作用是终止函数的执行,return只执行一次,后面的内容不执行

def ret():
    print(111)
    return
    print(222)

re = ret()
print(re)

二、函数参数

只写return

函数的参数分为形式参数和实际参数,在函数定义的时候,函数名后面括号里的就是形式参数,在函数调用的时候,传递的参数是实际参数。形式参数只在函数内部有效,外部无法引用。

图片 5图片 6

1.形参

def ret():
    print(111)
    return None
    print(222)

re = ret()
print(re)

1)位置参数:按照从左到右的顺序依次定义的参数 def foo(x,y,z)

return None

  位置形参必须被传值,且多一个少一个都不行

    b、返回值不为None

2)默认参数:在函数定义阶段就已经为形参赋值,调用阶段不赋值也会有默认值
def foo(x,y=10)

         1、返回一个值

  值经常变化的情况,通常定义成位置参数,但是值在多数情况下不变的情况下,可以定义成默认参数

图片 7图片 8

注意:

def mylen():
    """计算s1的长度"""
    s1 = "hello world"
    length = 0
    for i in s1:
        length = length+1
    return length

str_len = mylen()
print(str_len)

a.默认参数必须放在位置参数后面

返回一个值

b.默认参数通常定义成不可变类型

          2、返回多个值

c.默认参数只在定义时被赋值一次

5、函数的调用—-接受返回值

3)命名关键字参数:def register(*,name,age)
*后面定义的形参,必须被传值,且必须以关键字的形式传值

   a、返回值为None    不接受

2.实参

   b、返回值不为None

1)位置实参:与位置形参一一对应

       1、返回一个值

2)关键字参数:实参在定义时,按照key-values的形式定义

               用一个变量接受

  def foo(x,y)

       2、返回多个值

  foo(x=1,y=2)

               a、用一个变量接受,接受的结果是一个元祖

  关键字参数可以不用向位置参数一样与形参一一对应,可以打破顺序限制

               b、有多少个返回值就用多少个值接受

注意:a.位置参数和关键字参数混合使用的时候,位置参数必须在关键字参数前面

6、参数

   b.既可以是位置实参形式,也可以是关键字实参形式,但是一个形参只能传值一次

    a、参数—-站在定义函数的角度

3)可变长参数:

         1、位置参数

  按位置定义的可变长参数用*表示

         2、默认参数

  按关键字定义的可变类型的参数用**表示  

         3、动态参数

def func(x,y,*args):
    print(x,y,args)
func(1,2,3,4,5)  --->1 2 (3 4 5)

              a、*args

#遇到*就是位置参数,把*后面的全部拆开,再一一匹配,多余的就以元组的形式存放到一起

              b、**kwargs

def func(x,y,**kwargs):
    print(x,y,kwargs)
func(1,y=2,z=3,a=1,b=2)---->1 2 {'z': 3, 'a': 1, 'b': 2}

顺序:位置参数、*args、默认参数、**kwargs

#遇到**就是关键字参数,把**后面的全部拆成关键字,再一一匹配,多余的以字典形式存放到一起

     b、参数—-站在调用函数的角度上

def wrapper(*args,**kwargs):可以接受任意形式,任意长度的参数

         1、按照位置传参

参数的定义顺序:x,y=1,*args,z,**kwargs,分别是位置参数,默认参数,可变长位置参数,命名关键字参数,可变类型参数

         2、按照关键字传参

但需要注意的是,这些参数并不会同时全部出现

         3、动态传参*tup,**dic

三、名称空间和作用域

7、参数分为形参和实参   

名称空间存放名字和值的绑定关系,以key-value 的形式

     a、实参:调用函数的时候传入的参数

在Windows命令提示行中输入命令:import this ,在最后一行会看到这样一句话:

8、位置参数

  Namespaces are one honking great idea — let’s do more of those!

     a、位置参数必须传值

名称空间分为三种:

图片 9图片 10

1)内置名称空间:Python自带的,如print,int,len….当Python解释器启动的时候,就会生成内置名称空间

def aaa(a,b):
    print(a,b)
aaa(1,2)

2)全局名称空间:文件级别定义的名字会存放到全局名称空间,执行Python程序的时候产生,简单点说就是没有缩进的变量名

位置参数

3)局部名称空间:定义在函数(或模块、类)内部的名字,只有在函数(模块、类)调用的时候才生效,调用结束后就会释放

9、默认参数

加载顺序是:内置名称空间–>全局名称空间–>局部名称空间

     a、默认参数可以不传值

取值顺序是:局部名称空间–>全局名称空间–>内置名称空间

图片 11图片 12

四、函数嵌套和作用域

def bbb(x=10):
    print(x)
 bbb()     #x = 10
 bbb(20)  #x = 20

1.函数嵌套包括函数的嵌套调用和函数的嵌套定义

默认参数

函数嵌套调用可以用求最大值的例子来说明:

10、动态参数

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

print(max4(11,23,-7,31))

图片 13图片 14

函数嵌套定义:

def ccc(*args):#1,2,3,4,5
    print(args)

ccc(1,2,3,4,5)#按位置传参数

t = (1,2,3,4,5)
ccc(t)  ((1, 2, 3, 4, 5),)
ccc(*t)  (1, 2, 3, 4, 5)
复制代码
def f1():
    def f2():
        def f3():
            print('from f3')
        print('from f2')
        f3()
    print('from f1')
    f2()
# print(f1)
f1()

动态参数

2.作用域

图片 15图片 16

1)全局作用域:内置名称空间与全局名称空间的名字属于全局范围,在整个文件的任意位置都能引用

def ddd(**kwargs):
    print(kwargs)

 ddd(k = 'a',j = 'b')#按关键字传参数

2)局部作用域:属于局部范围,只在函数内部可以被引用,局部有效

动态参数+关键字参数

一定要注意局部变量和全局变量的作用范围,在局部修改全局变量会出错,在全局范围引用局部变量也会出错

图片 17图片 18

作用域在函数定义时就已经固定了,不会因调用位置而改变

def eee(*args,**kwargs):
    print(args,kwargs)

 eee(12,123)

但是如果一定要在局部修改全局变量,也是用办法的,就是在要修改的变量前加一个global

动态,先按位置参数,再按关键字参数

x=1
def foo():
    x=10
    print(x)        

foo()       #10
print(x)    #1

x=1
def foo():
    global x
    x=10
    print(x)

foo()       #10
print(x)    #10

def foo():
    x=1
    def f2():
        x+=x
        return x
    return f2()

print(foo())        #会报错UnboundLocalError: local variable 'x' referenced before assignment

def foo():
    x=1
    def f2():
        nonlocal x  #告诉Python解释器,这里的x不是局部变量,只会找函数内部的,不会修改全局变量
        x+=x
        return x
    return f2()

print(foo())    #会打印出修改后的x的值,2

11、命名空间

五、闭包函数

     a、命名空间分为三种

定义在函数内部的函数,该内部函数包含对外部作用域,而非全局作用域的名字的引用,那么该内部函数称为闭包函数

            1、全局命名空间

name='egon'
def func():
    name='alex'
    def bar():
        print(name)
    return bar

f=func()        #f就是闭包函数
print(f.__closure__[0].cell_contents)       #该命令可以查看闭包函数外面包了什么东西------>alex

            2、局部命名空间

闭包函数的特点:a.自带作用域,b.延迟计算(f只是拿到了函数的内存地址,什么时候用,加括号就可以运行)

            3、内置命名空间

闭包函数最基本的形式:

     b、三种命名空间的顺序:内置命名空间>全局命名空间>局部命名空间

def 外部函数名():

     c、取值

  内部函数需要的变量

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

  def 内部函数名():

图片 19图片 20

    引用外部变量

x = 1
def f(x):
    print(x)

print(10)

  return 内部函数名

View Code

六、装饰器

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

1.开放封闭原则:对扩展是开放的,对修改是封闭的

图片 21图片 22

2.装饰器本质是任意可调用的对象,被装饰对象也是任意可调用的对象

x = 1
def f(x):
    print(x)

f(10)
print(x)

3.装饰器的功能是:在不修改被装饰对象源代码及调用方式的前提下,为其添加新的功能

View Code

4.装饰器语法:在被装饰对象的正上方的单独一行,写上@装饰器名字

12、作用域

5.有多个装饰器的时候,每行一个,执行时从上往下运行

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

6.被装饰函数有参数的情况:写成(*args,**kwargs)的形式

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

装饰器示例一:

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

#实现缓存网页内容的功能,下载的页面存放于文件中,如果文件内有值(文件大小不为0),
# 就优先从文件中读取网页内容,否则,就去下载,然后存到文件中
from urllib.request import urlopen
import os

cache_path=r'C:untitled615Python第8天cache_file.txt'
def make_cache(func):
    def wrapper (*args,**kwargs):
        if os.path.getsize(cache_path):
            #有缓存
            print('33[45m========>有缓存33[0m')
            with open(cache_path,'rb') as f:
                res=f.read()
        else:
            res=func(*args,**kwargs)#下载
            with open(cache_path,'wb') as f:#制作缓存
                f.write(res)
        return res
    return wrapper


@make_cache

def get(url):
    return urlopen(url).read()


print(get('https://www.python.org'))
作用域:
小范围的可以用大范围的
但是大范围的不能用小范围的
范围从大到小(图)
在小范围内,如果要用一个变量,是当前这个小范围有的,就用自己的
如果在小范围内没有,就用上一级的,上一级没有就用上上一级的,以此类推。
如果都没有,报错

装饰器示例二:

13、闭包

#为多个函数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,后续的函数都无需再输入用户名和密码
db_dic={
    'egon':'123',
    'alex':'alex3714',
    'yuanhao':'smallb'
}


db_path=r'C:untitled615Python第8天db_dic.txt'

with open(db_path,'w',encoding='utf-8') as f:
    f.write(str(db_dic))

login_dic={
    'user':None,
    'status':False,
}

def auth(func):
    def wrapper(*args,**kwargs):

        #加一个验证状态的字典,如果已经登录成功,下次使用就不用重新验证
        if login_dic['user'] and login_dic['status']:
            res=func(*args,**kwargs)
            return res
        else:
            name=input('name:')
            password=input('password:')
            with open(db_path, 'r', encoding='utf-8') as f:
                auth_dic = eval(f.read())
            if name in auth_dic and password==auth_dic[name]:
                print('login ok')
                login_dic['user']=name
                login_dic['status']=True
                res=func(*args,**kwargs)
                return res
            else:
                print('error')
    return wrapper

@auth
def index():
    print('welcom to the page')

@auth
def home(name):
    print('welcom  to %s's home page'%name)


index()
home('egon')

       a、闭包分为:

七、迭代器

            1、闭:内部函数

1.对于字符串、列表、元组的数据类型,我们可以依据索引来实现迭代的效果,但是字典、集合这种没有索引的数据类型,就需要其他方式

            2、包:包含对外部函数的作用域中变量的引用

2.Python为了提供一种不依赖索引的迭代方式,为一些对象内置了__iter__方法,obj.__iter__()得到的结果就是迭代器

       b、闭包常用的的形式

得到的迭代器既有.__iter__方法,又有.__next__方法

图片 23图片 24

3.迭代器的优点:

def hei():
    x = 20
    def inner():
        print(x)  #局部的
    return inner

i = hei()
i()  #全局

  a.提供了一种不依赖索引的取值方式

闭包常用形式

  b.惰性计算,节省内存

14、函数值装饰器

4.迭代器的缺点:

      a、装饰器的本质:闭包函数

  a.取值不如按照索引取值方便

     
b、装饰器的功能:就是在不改变原函数调用方式的情况下,在这个函数的前后加上扩展功能

  b.一次 性的,取值只能往后走,不能往前退

图片 25图片 26

  c.无法获取迭代器的长度

def timer(func):
    def inner(a):
        start = time.time()
        func(a)
        print(time.time() - start)
    return inner

@timer
def func1(a):
    print(a)

func1(1)

5.for循环实际上会默认调用.__iter__方法

带参数的装饰器

6.判断是否是可迭代对象和迭代器,可以用命令

15、装饰器的开放封闭原则:

print(isinstance(str1,Iterable)) —>判断是否为可迭代对象

相关文章

No Comments, Be The First!
近期评论
    功能
    网站地图xml地图