zoukankan      html  css  js  c++  java
  • python基础编程: 函数示例、装饰器、模块、内置函数

    目录:

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

    一、函数示例:

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

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

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

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

    def foo():
        print('in the foo')
    
    foo() 

    有参函数:

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

    空函数:

    def func():
        pass

    空函数的应用示例:

    def put():
        pass
    
    def get():
        pass
    
    def cd():
        pass
    
    def ls():
        pass
    
    def auth():
        pass

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

    def foo():
        print('in the foo')
    
    foo()

    表达式形式:

    def my_max(x,y)
        if x>y:
            return x
        else:
            return y
    
    res = my_max(1,2)
    res = 10 * my_max(1,2)   
    作为另外一个函数的参数:
    my_max(1,my_max(2,3)): #先比较2与3的最大值,再与1作比较;    

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

    def foo():
        print('in the foo')
    
    res = foo()
    print(res)

    返回一个函数:

    def foo():
        return 1
    res = foo()
    print(res)

    返回多个:

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

    5、函数的参数:

    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、函数是第一类对象的意思就是函数可以被当作数据来传递;

    def func()
        print('in the fun')
    
    fl = fun
    fl()
    
    函数可作为参数:高阶函数:
    def foo(x):
        x()
    foo(func)
    
    返回值可以是函数:
    ##########################################
    
    可以作为容器类型的元素:
    func_dic={
        'func':func
    }
    
    func_diuc['func']()

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

    嵌套的调用:
    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、不能改变函数的调用方式;

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

    示例:

    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、得到一个模块名,绑定到该模块内的代码;

    为模块起别名:
    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()

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

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

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

    把文件当做和脚本执行__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 *

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

    此处是想从包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仍然不能导入)。

    示例:

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

    四、内置函数

    内置函数解释:
    
    # !/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('b23'))
    
    #将十进制转换为二进制;
    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__
    

      

      

  • 相关阅读:
    IDEA tomcat热部署方法及乱码问题解决
    访问WEB-INF下JSP资源的几种方式(转)
    SpringMVC 静态资源处理
    SpringMVC中的拦截器
    SpringMVC中的异常处理
    SpringMVC实现文件上传
    IDEA 热部署
    响应数据和结果视图
    SpringMVC中的常用注解
    js获取当前根目录的方法
  • 原文地址:https://www.cnblogs.com/hsggj/p/6402808.html
Copyright © 2011-2022 走看看