• 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))
  • 相关阅读:
    我的WCF之旅(1):创建一个简单的WCF程序
    网页设计中颜色的搭配
    CSS HACK:全面兼容IE6/IE7/IE8/FF的CSS HACK
    UVa 1326 Jurassic Remains
    UVa 10340 All in All
    UVa 673 Parentheses Balance
    UVa 442 Matrix Chain Multiplication
    UVa 10970 Big Chocolate
    UVa 679 Dropping Balls
    UVa 133 The Dole Queue
  • 原文地址:https://www.cnblogs.com/charliedaifu/p/9862598.html
Copyright © 2020-2023  润新知