zoukankan      html  css  js  c++  java
  • Python基础知识:函数

    1、定义函数和调用函数

    #定义函数def
    def greet_user(username):
        '''简单的问候语'''
        print('Hello,%s!'%username)
    greet_user('jack')#调用函数

    2、形参和实参,实参的顺序很重要

    def describe_flower(flower_type,flower_color='yellow'):
        print("My favorite flower is %s."%flower_type)
        print("My favorite %s is %s."%(flower_type,flower_color))
    describe_flower('rose','red')
    describe_flower(flower_type='lily',flower_color='white')
    describe_flower(flower_type='babysbreath')#没有提供实参的形参将调用默认值
    print('----------')

    3、定义一个返回字典的函数

    #返回字典
    def make_album(singer_name,album_name,num_of_songs=''):
        info_of_album={'singer':singer_name,'album':album_name}
        if num_of_songs:
            info_of_album['number']=num_of_songs
        return info_of_album
    album1=make_album('周杰伦','十一月的肖邦')
    album2=make_album('许嵩','寻雾启事','12')
    print(album1)
    print(album2)

    4、在函数中修改列表

    def make_great(magicians):
        for i in range(len(magicians)):
            magicians[i] = 'The great ' + magicians[i]
        print(magicians)    
    def show_magicians(magicians):
        for magician in magicians:
            print(magician)
    mags = ['jack','alex','james']
    make_great(mags)
    show_magicians(mags)

    5、[:]切片法创建列表副本,不改变原列表

    def make_great(magicians,new_magicians):
        for i in range(len(magicians)):
            magicians[i] = 'The great ' + magicians[i]
            new_magicians.append(magicians[i])
        print(new_magicians)    
    def show_magicians(magicians):
        for magician in magicians:
            print(magician)
    mags = ['jack','alex','james']
    new_mags = []
    make_great(mags[:],new_mags)#函数调用列表副本
    show_magicians(mags)
    show_magicians(new_mags)

    6、结合使用位置实参和任意数量实参,Python将先匹配位置实参和关键字实参,再将余下的实参都收集到最后一个形参中;*表示建立一个名为topping的空元组。

    #将多余实参全部存放到空元组中
    def make_sandwich(size,*toppings):
        print('I will make a %s-inch sandwich with the following toppings:'
        %str(size))
        for topping in toppings:
            print('- %s'%topping)
    make_sandwich(12,'sausages')
    make_sandwich(16,'sausages','mushrooms')

    7、使用任意数量的关键字实参;**表示建立一个名为user_info的空字典

    #将收到的所有键-值对都封装到这个字典中
    def build_profile(first,last,**user_info):
        profile = {}
        profile['first_name'] = first
        profile['last_name'] = last
        for key,value in user_info.items():
            profile[key] = value
        return profile
    user_profile = build_profile('james','lebran',
                  location='shanghai',
                  hobby='football')
    print(user_profile)

    8、import 调用模块中函数的几种方法

    #导入整个模块,就可以使用模块中所有的函数
    import func
    func.make_car()
    #导入特定的函数
    from func import make_car
    make_car()
    #调用模块中的函数,并指定别名
    from func import make_car as mc
    car=mc('subaru','outback',color='blue',tow_package=True) 
    print(car)
    #调用模块中所有函数
    from func import *   
    make_sandwich(16,'sausages','mushrooms')

    9、%运算符,相除返回余数

    #--%--运算符
    number = 10
    print(number%2)
    print(number%3)

    10、运算符**表示乘方;2**3表示2的3次方

    #for循环求64是2的几次方
    a = 64
    i = 0
    for i in range(100):
        a /= 2
        i += 1
        if a == 1:
            print(i)
            break
    #while循环求64是2的几次方
    a = 64
    i = 0
    while True:
        a /= 2
        i += 1
        if a == 1:
            print(i)
            break
        else:
            continue

    11、循环语句中的特殊语句

    • continue :跳出本次循环;

    • break:跳出所有循环;

    • 执行return之后,不再执行下面的代码,如果函数中没有return,Python将自动返回一个值None。

    12、函数中的默认参数必须放到参数设置的末尾,例如def send(a,b,c="10")

    13、元组动态参数*args的两种情况:

    • 第一种:实参不带*将实参放到args这个元组中,传递给函数,无论实参是一个列表还是字符串,都将作为元组的一个元素;

    • 第二种:实参带*,就把实参列表里的每个元素加入到元组中

    def send(*args):
        print(args,type(args))
    a = [11,22,'ddd']
    send(a)
    send(*a)
    
    #([11, 22, 'ddd'],) <class 'tuple'>
    #(11, 22, 'ddd') <class 'tuple'>

    14、字典动态参数**args:默认将传入的参数,全部放入字典中。实参中必须包含key和value

    def send(**args):
        print(args,type(args))
    send(a=1,b=2)
    dic = {'a':1,'b':2}
    send(n=dic)
    send(**dic)
    
    #{'a': 1, 'b': 2} <class 'dict'>
    #{'n': {'a': 1, 'b': 2}} <class 'dict'>
    #{'a': 1, 'b': 2} <class 'dict'>

    15、万能参数:同时使用*args和**kwargs:顺序不能反,一个*必须放在前面

    def send(*args,**kwargs):
        print(args,type(args))
        print(kwargs,type(kwargs))
    send(1,2,3,a='1',b='2')
    
    #(1, 2, 3) <class 'tuple'>
    #{'a': '1', 'b': '2'} <class 'dict'>

    16、全局变量

    • 定义全局变量默认字母全部大写;

    • 如果想在函数中对全局变量重新赋值,需要加入global;

    • 如果全局变量是列表或字典,函数中可以修改全局变量,比如添加删除元素。

    #全局变量,任何作用域都可以读取
    NAME = 'alex'
    def f1():
        print(NAME)
    def f2():
        #修改全局变量
        global NAME
        NAME = 'alice'
        print(NAME)
    def f3():
        print(NAME)
    f1()
    f2()
    f3()
    
    #alex
    #alice
    #alice

    17、两个函数之间加两个空行,函数下面的波浪线就消失了,这样才符合函数的规范操作。

    18、练习题:为每个函数添加注释要养成习惯,注释要放在双引号中,单引号会出现波浪线,不规范

    def login(username,password):
        """
        用于用户登陆
        :param username: 用户输入的用户名
        :param password:用户输入的密码
        :return:True表示登陆成功,False表示登陆失败
        """
        t = open('text_fileKJ', 'r')
        for line in t:
            line_list = line.strip().split('|')
            if username == line_list[0] and password == line_list[1]:
                return True
        return False
    def register(username,password):
        """
        用于用户注册
        :param username: 用户输入的用户名
        :param password: 用户输入的密码
        :return: 默认返回None
        """
        t = open('text_fileKJ', 'a')
        user_info = '
    ' + username + '|' + password
        t.write(user_info)
        t.close()
    def main():
        """
        让用户选择登陆或注册
        """
        user_input = input('1:登陆;2:注册:')
        if user_input == '1':
            user = input('请输入账户名:')
            pwd = input('请输入密码:')
            user_login = login(user,pwd)
            if user_login:
                print('登陆成功')
            else:
                print('登陆失败')
        elif user_input == '2':
            user = input('请输入账户名:')
            pwd = input('请输入密码:')
            register(user, pwd)
    main()

    19、lambda表达式

    • 就是简单函数的另一种表达方式,只能有一行

    • =前面是函数名,:前面是参数

    #def函数
    def f1(a):
        return a + 100
    #lambda表达式
    f2 = lambda a,b:a + b + 100
    ret1 = f1(10)
    print(ret1)
    ret2 = f2(10,20)
    print(ret2)
    #设置默认值
    f3 = lambda a,b=10:a + b + 100
    ret3 = f3(10)
    print(ret3)

    20、Python内置函数

    #abs( )--取绝对值
    a = -1
    print(abs(a))
    #bool( )--返回布尔值(False:0,None,"",[],(),{})
    print(bool(None))
    #all( )--括号内接受一个可迭代的数据集,数据集中的每个元素都为真,函数的返回值才为True;
    a = all([0,1,2,3])
    print(a)
    #any( )--括号内也是一个可迭代数据集,任意一个元素为真,就为真;
    a = any([0,0,0,3])
    print(a)
    #ascii( )自动执行类的__repr__
    class Name():
        def __repr__(self):
            return 'abc'
    n = ascii(Name())
    print(n)
    #bin()接受一个十进制,转换成一个二进制
    print(bin(8))#结果为0b1000,0b为二进制标识,8的二进制为1000
    #oct()十进制转八进制
    print(oct(9))#结果为0o11,0o标识八进制
    #hex()十进制转十六进制
    print(hex(15))#结果为0xf,0x标识十六进制
    #UTF-8 一个汉字,三个字节,一个字节8位;
    #gbk  一个汉字,两个字节;
    #bytes(字符串,encoding=编码类型)把字符串转换为一个字节类型
    s = "小明"
    print(bytes(s,encoding='utf-8'))#b'xe5xb0x8fxe6x98x8e'
    print(bytes(s,encoding='gbk'))#b'xd0xa1xc3xf7'
    #bytearray()将每个字节存储为一个数组的元素
    print(bytearray(s,encoding='utf-8'))
    #字节类型转字符串,用同样的编码才能往回转换
    n = bytes("小芳",encoding='utf-8')#字节类型
    print(str(n,encoding='utf-8'))
    #文件操作
    filename = 'text_filecats.txt'
    with open(filename,'r') as f1:#只读
    with open(filename,'w') as f2:#先清空文件,只写
    with open(filename,'x') as f3:#文件存在,报错,不存在,创建并只写
    with open(filename,'a') as f4:#追加内容
    #读取文件时,出现乱码,很可能是编码语言选择错误
    with open('text_fileword.txt','r',encoding='gbk') as f5:
         contents = f5.read()
         print(contents)
    #rb,wb,xb,ab,r+b,w+b,x+b,a+b后面带b的,表示直接以字节的方式处理
    with open(filename,'rb') as f:
        data = f.read()
         print(data,type(data))
    #b'xe5xb0x8fxe7xb1xb3
    ' <class 'bytes'>
    #把二进制数据添加到文件,需要bytes先转换为字符串
     with open(filename,'ab') as f:
         data = f.write(bytes('小芳',encoding='utf-8'))
    #f.seek(n)指针跳转到n指定的位置(字节)
    #f.write()当前指针位置开始向后覆盖,n代表字节的位置
    #f.tell()获取文件当前指针的字节位置
    #r+,既能读,又能写;如果打开模式无b,read按照字符读取,有b,按字节
    #无b,f.read(1)读取第一个字符,有b,读取第一个字节
    with open('text_filecats.txt','r+',encoding='utf-8') as f5:
         contents = f5.read(1)
         print(contents)#读取第一个字:小
    #a+,无论你怎么调整指针位置,写入时都会写在最后
    #w+,先清空内容,再写入,才能读取刚才写入的内容
    #使用open,close,打开读写文件
     f = open(filename,'r')
     f.write('111')
     f.close()
    # f.flush()强制刷入硬盘
    # f.readable()是否可读
    # f.readline()只读取一行
    # f.seekable()指针是否可操作
    # f.truncate()截断:把指针位置后面的数据都清空
    # for line in f: 按行循环文件对象
    # 同时打开两个文件,最后同时关闭
    # 例如:想把一个文件的内容修改一个人名后写入另一个文件
     with open('db1','r') as f1,open('db2','a') as f2:
         for line in f1:
             new_line = line.replace('alex','alice')
             f2.write(new_line)
    #将ascii码对照表里十进制转换为字母
    r = chr(100)
    print(r)#d
    #将ascii码对照表里字母转换为十进制
    n = ord("d")
    print(n)#100
    #random随机返回一串验证码;ascII码表里65-90为大写字母
    import random
    li = []
    for i in range(4):
        r = random.randrange(0,5)
        if r == 1 or r == 3:
            num1 = random.randrange(0,10)
            li.append(str(num1))
        else:
            num2 = random.randrange(65,91)
            li.append(chr(num2))
    print(li)
    temp = ''.join(li)#join()把列表拼接成字符串
    print(temp)
    #compile()编译成Python代码
    s = "print(123)"
    r = compile(s,"<string>","exec")
    #exec()执行Python代码;接受代码或者字符串,没有返回值
    exec(r)
    #eval()将字符串转换成Python代码,并获取结果
    #函数只能执行表达式代码
    r = "8*8"
    ret = eval(r)
    print(ret)
    #dir()快速查看一个对象提供了哪些功能
    print(dir(random))
    #help()查看对象提供的详细功能
    #divmod()接受两个整数,得到商和余数
    #第一种,可以将返回值赋给两个变量
    a,b = divmod(97,10)
    print(a,b)
    #第二种,可以当成一个元组
    n = divmod(98,10)
    print(n[0])
    print(n[1])
    #判断对象是否是某个类的实例
    r = "abc"
    print(isinstance(r,str))#True
    '''filter(函数,可迭代的对象),循环第二个参数,
    对参数的每一个元素执行函数,如果函数返回True,
    就把这个元素加入结果,否则就舍弃
    '''
    def f(a):
        if a >2:
            return True
    li = [1,2,3,4]
    ret = filter(f,li)
    print(list(ret))#记得要以列表的形式输出
    #以lambda表达式实现
    ret = filter(lambda a:a>3,li)
    print(list(ret))
    '''map(函数,可迭代的对象),循环第二个参数,
    对参数的每一个元素执行函数,将函数返回值存放到结果
    '''
    li = [1,2,3]
    ret = map(lambda a:a+100,li)
    print(list(ret))#[101, 102, 103]
    #globals()返回所有全局变量
    #locals()返回所有局部变量
    #hash()返回一个对象的hash值,一般用于存储字典的key
    #id()查看内存地址
    s = "sss"
    print(id(s))#327689119312
    #issubclass()判断一个类是否是另一个类的子类
    #Python2中字符长度按字节来算,3中按字符来算
    #len('小明')2中返回6,3中返回2
    #pow(2,10)求2的10次方
    #rount()四舍五入
    #slice()切片
    #zip()将列表的相同索引的值放到一个元组中
    l1 = ['a',1,2]
    l2 = ['b',1,2]
    l3 = ['c',1,2]
    r = zip(l1,l2,l3)
    ret = list(r)[0]
    print(' '.join(ret))
    

     21、装饰器:@函数名

    • 本质上就是函数,功能是为其他函数添加附加功能,前提是不改变装饰函数的源代码和调用方式;
    • 高阶函数+函数嵌套+闭包
    • 高阶函数:函数的参数或者返回值是一个函数名
    • 函数嵌套:在函数内部定义函数
    • 闭包:在一个作用域里放入定义变量,相当于打了一个包
    • @函数名 是python的一种语法糖
    #函数名可以当做参数传递
    def f1():
        print(123)
    def f2(xx):
        xx()
    f2(f1)#123
    #装饰器@+函数名,有两个功能:
    #1、自动执行outer函数并将其下面的函数名f1当做参数传递
    #2、将outer函数的返回值重新赋值给f1=inner
    #3、万能参数*args,**kwargs,接受任何数量的参数
    def outer(func):
        def inner(*args,**kwargs):
            print("before")
            r = func(*args,**kwargs)
            print("after")
            return r
        return inner
    @outer #相当于f1=outer(f1),返回的是inner的内存地址f1=inner,然后f1(args)执行inner(args)函数
    def f1(args):
        print(args)
        return "fff" + args
    ret = f1("ddd")#其实是在运行inner函数,最终得到inner函数的返回值
    print(ret)

     22、生成器,有两种表达方式

    • 生成器表达式:m=(i for i in range(10))    m.__next__()

    • 生成器函数:其实就是由函数改造而来,具有生成能力的函数,标识:函数内部有yield,相当于return,但是可以执行多次

    def func():
        print(111)
        yield 1
        print(222)
        yield 2
    ret = func()#得到一个生成器
    print(ret)#<generator object func at 0x00000061358BA138>
    #进入函数执行函数,直到遇到yield,获取yield后面的数据,输出
    r1 = ret.__next__()
    print(r1)#111,1
    r2 = ret.__next__()
    print(r2)#222,2
    #利用生成器创造一个循环函数
    def myrange(arg):
        start = 0
        while True:
            if start > arg:
                return
            yield start
            start += 1
    ret = myrange(3)
    r = ret.__next__()
    print(r)
    r = ret.__next__()
    print(r)

    23、迭代器:就是一个封装了调用函数__next__的循环,让我们不用一步一步调用__next__函数

    • 凡是可作用于for循环的对象都是Iterable类型(可迭代对象);

    • 凡是可作用于next()函数的对象都是Iterator类型(迭代器对象),它们表示一个惰性计算的序列;

    • 生成器都是Iterator对象,生成器不但可以作用于for循环,还可以被next()函数不断调用并返回下一个值,直到最后抛出StopIteration错误表示无法继续返回下一个值了
    • 集合数据类型如listdictstr等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。

    • Python的for循环本质上就是通过不断调用next()函数实现的;

    24、递归:自己调用自己

    #递归应用于用户重复登录
    def login():
        inp = input("输入姓名")
        if inp == "admin":
            print("success")
        else:
            return login()
    login()
    #递归实现从1循环加到7
    def add(n):
        n += 1
        if n <7:
            return add(n)
        else:
            return n
    r = add(1)
    print(r)#7
    #递归实现1*2*3*4*5*6*7=5040
    def mul(m,n):
        n += 1
        m *= n
        if n < 7:
            return mul(m,n)
        return m
    ret = mul(1,1)
    print(ret)#5040
    #另一种方法
    def func(num):
        if num == 1:
            return 1
        return num * func(num-1)
    ret = func(7)
    print(ret)

    练习:递归实现斐波那契数列 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368

    def fib(max):
        n, a, b = 0, 0, 1
        while n < max:
            yield b
            a, b = b, a + b
            n = n + 1
        return 'done'

    25、反射

    • 利用字符串的形式去对象(模块)中(寻找/检查/删除/设置)成员

    • getattr()寻找、hasattr()检查、delattr()删除、setattr()设置

    • 通过字符串导入模块:

      • obj = __import__("xxx")

      • obj = __import__("file.xxx", fromlist=True)

    def func():
        inp = input("请输入你要访问的URL(模块名/函数名):")
        #hasattr()检查对象中是否包含该成员,是返回True
        m, h = inp.split("/")
        #__import__通过字符串导入模块,obj.func()调用函数
        obj = __import__(m)
        #如果模块在文件夹中,后面加个参数fromlist,意思是按前面的指定路径导入
        #obj = __import__("lib." + m, fromlist=True)
        if hasattr(obj,h):
            #getattr()获取对象中的成员
            func = getattr(obj,h)
            func()
        else:
            print("404")

    26、解压序列

    a,b,c=(1,2,3)
    a=1
    b=2
    c=3
    #取开头和结尾的值
    l=[1,2,3,4,5]
    a,*_,b=l
    a=1
    b=5
    #*加一个变量,可以是任意字符,表示中间的所有值

     27、冒泡算法

    需求:请按照从小到大对列表 [13, 22, 6, 99, 11] 进行排序

    思路:相邻两个值进行比较,将较大的值放在右侧,依次比较!

    li = [13, 22, 6, 99, 11]
    def func(arg):
        for i in range(1,len(arg)):
            for m in range(len(li) - i):
                if arg[m] > arg[m+1]:
                    arg[m],arg[m+1] = arg[m+1],arg[m]
        print(arg)
    
    func(li)

     28、列表转字典

    status_choice = [(1, '上线'), (2, '下线')]
    
    status_list = list(map(lambda x:{'id':x[0],'name':x[1]},Video.status_choice))
  • 相关阅读:
    XML传输数据导致的安全问题
    XML的学习
    docker的笔记
    对于glog中ShutdownGoogleLogging后不能再次InitGoogleLogging问题的解决办法
    游戏分类英文缩写
    带属性的向前声明:warning: type attributes are honored only at type definition
    linux GCC编译错误:CPU you selected does not support x8664 instruction set
    电商数据分析
    日常电脑软件推荐清单
    优秀开源组合:助你快速研发
  • 原文地址:https://www.cnblogs.com/charliedaifu/p/9862598.html
Copyright © 2011-2022 走看看