zoukankan      html  css  js  c++  java
  • [Python笔记]第三篇:深浅拷贝、函数

    本篇主要内容:深浅拷贝,自定义函数,三目运算,lambda表达式,

    深浅拷贝

    一、数字和字符串

    对于 数字 和 字符串 而言,赋值、浅拷贝和深拷贝无意义,因为其永远指向同一个内存地址。

    import copy
    # ######### 数字、字符串 #########
    n1 = 123
    # n1 = "i am alex age 10"
    print(id(n1))
    # ## 赋值 ##
    n2 = n1
    print(id(n2))
    # ## 浅拷贝 ##
    n2 = copy.copy(n1)
    print(id(n2))
      
    # ## 深拷贝 ##
    n3 = copy.deepcopy(n1)
    print(id(n3))
    

      

     

    二、其他基本数据类型

    对于字典、元祖、列表 而言,进行赋值、浅拷贝和深拷贝时,其内存地址的变化是不同的。

    1、赋值

    赋值,只是创建一个变量,该变量指向原来内存地址,如:

    n1 = {"k1": "wu", "k2": 123, "k3": ["alex", 456]}
      
    n2 = n1
    

      

    2、浅拷贝

    浅拷贝,在内存中只额外创建第一层数据

    import copy
     
    n1 = {"k1": "wu", "k2": 123, "k3": ["alex", 456]}
     
    n3 = copy.copy(n1)
    

      

    3、深拷贝

    深拷贝,在内存中将所有的数据重新创建一份(排除最后一层,即:python内部对字符串和数字的优化)

    import copy
      
    n1 = {"k1": "wu", "k2": 123, "k3": ["alex", 456]}
      
    n4 = copy.deepcopy(n1)
    

     

     

    >>> import copy
    >>> n1 = {"k1": "wu", "k2": 123, "k3": ["alex", "eric"]}
    >>> n2 = n1
    >>> n3 = copy.copy(n1)
    >>> n4 = copy.deepcopy(n1)
    >>> n1['k1'] = 'lee'
    >>> n1['k3'][0] = "tim"
    >>> print(n3)
    {'k1': 'wu', 'k2': 123, 'k3': ['tim', 'eric']}    # 浅拷贝
    >>> print(n4)
    {'k1': 'wu', 'k2': 123, 'k3': ['alex', 'eric']}          # 深拷贝
    >>>
    View Code

    三目运算

    三目运算也叫三元运算,是对简单的条件语句的缩写。

    1 # 书写格式
    2  
    3 result = 值1 if 条件 else 值2
    4  
    5 # 如果条件成立,那么将 “值1” 赋值给result变量,否则,将“值2”赋值给result变量

    lambda表达式

    学习条件运算时,对于简单的 if else 语句,可以使用三元运算来表示,即:

    # 普通条件语句
    if 1 == 1:
        name = 'wupeiqi'
    else:
        name = 'alex'
        
    # 三元运算
    name = 'wupeiqi' if 1 == 1 else 'alex'

    对于简单的函数,也存在一种简便的表示方式,即:lambda表达式也叫匿名函数

    # ###################### 普通函数 ######################
    # 定义函数(普通方式)
    def func(arg):
        return arg + 1
        
    # 执行函数
    result = func(123)
        
    # ###################### lambda ######################
        
    # 定义函数(lambda表达式)
    my_lambda = lambda arg : arg + 1
        
    # 执行函数
    result = my_lambda(123)
    # 不带参数的lambda表达式
    ret1 = (lambda arg: arg + 3)(100)
    # 带参数的lambda表达式
    ret2 = (lambda arg: arg + 3 if arg % 2 == 0 else arg)(99)
    print(ret1)
    print(ret2)
    带参数的lambda表达式

    自定义函数

    一、函数背景知识

    在学习函数之前,我们一直遵循:面向过程编程。

    即:根据业务逻辑从上到下实现功能,其往往用一长段代码来实现指定功能,

    开发过程中最常见的操作就是粘贴复制,也就是将之前实现的代码块复制到现需功能处,如下:

    while True:
        if cpu利用率 > 90%:
            #发送邮件提醒
            连接邮箱服务器
            发送邮件
            关闭连接
        
        if 硬盘使用空间 > 90%:
            #发送邮件提醒
            连接邮箱服务器
            发送邮件
            关闭连接
        
        if 内存占用 > 80%:
            #发送邮件提醒
            连接邮箱服务器
            发送邮件
            关闭连接
    

      

    这段代码if语句下面都是重复的内容,于是有了更简练的表达就有了:

    def 发送邮件(内容)
        #发送邮件提醒
        连接邮箱服务器
        发送邮件
        关闭连接
        
    while True:
        
        if cpu利用率 > 90%:
            发送邮件('CPU报警')
        
        if 硬盘使用空间 > 90%:
            发送邮件('硬盘报警')
        
        if 内存占用 > 80%:
    

      

    没错,上面的代码就是函数了!

    对于上述的两种实现方式,第二次必然比第一次的重用性和可读性要好,其实这就是函数式编程和面向过程编程的区别

    • 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可
    • 面向对象:对函数进行分类和封装,让开发“更快更好更强...”

    函数式编程最重要的是增强代码的重用性和可读性

    二、函数的定义和使用

    def 函数名(参数):
           
        ...
        函数体
        ...
        返回值
    

      

    函数的定义主要有如下要点:

    • def:表示函数的关键字
    • 函数名:函数的名称,日后根据函数名调用函数
    • 函数体:函数中进行一系列的逻辑计算,如:发送邮件、计算出 [11,22,38,888,2]中的最大数等...
    • 参数:为函数体提供数据
    • 返回值:当函数执行完毕后,可以给调用者返回数据。

    以上要点中,比较重要有参数和返回值:

    1、返回值

    函数是一个功能块,该功能到底执行成功与否,需要通过返回值来告知调用者。

    以上要点中,比较重要有参数和返回值:

    def 发送短信():
           
        发送短信的代码...
       
        if 发送成功:
            return True
        else:
            return False
       
       
    while True:
           
        # 每次执行发送短信函数,都会将返回值自动赋值给result
        # 之后,可以根据result来写日志,或重发等操作
       
        result = 发送短信()
        if result == False:
            记录日志,短信发送失败...
    

      

    2、参数

    为什么要有参数?

    参数是由函数封装者提供的功能定义。通过传入参数,函数使用者就无需只要函数内部工作细节就能完成一些复杂的运算操作

    没有参数

    def cpu_alrt():
        #发送邮件提醒
        # 连接邮箱服务器
        # 发送邮件
        # 关闭连接
    
    def disk_alrt():
        #发送邮件提醒
        # 连接邮箱服务器
        # 发送邮件
        # 关闭连接
    
    def ram_alrt():
        #发送邮件提醒
        # 连接邮箱服务器
        # 发送邮件
        # 关闭连接
    
    while True:
    
        if cpu > 90%:
            cpu_alrt()
    
        if disk > 90%:
            disk_alrt()
    
        if ram > 80%:
            ram_alrt()

    有参数实现

    def alrt(默认参数):
        #发送内容
    
    while True:
    
        if cpu > 90%:
            alrt("cpu alrt")
    
        if disk > 90%:
            alrt("disk alrt")
    
        if ram > 80%:
            alrt("ram alrt")
    3.三种参数

    普通参数

    普通参数的情况下,函数括号里面的叫做形式参数,调用函数而传入的叫实际参数.

    普通参数的传递并没有个数和数据类型的限制,可以传递字符串,数字,列表和字典。

    但参数必须按照函数定义时的顺序依次传入他们。

    # 定义函数
    def argtest(arg1,arg2,arg3):
        print('hello everyone, %s' % arg1)
        for k, v in arg2.items():
            print('my %s is %s' % (k, v))
        print("I like %s" % ' and '.join(arg3))
    
    st = 'my name is john'
    li = ['running', 'swimming', 'diving']
    dic = {"age": 18, "gender": "male"}
    
    # 依次传入字符串;字典;列表
    argtest(st, dic, li)
    
    """
    hello everyone, my name is john
    my age is 18
    my gender is male
    I like running and swimming and diving
    """

    默认参数

    默认参数是在定义函数的时候给参数赋一个默认值,默认参数需要定义在普通参数的后面,允许有多个默认参数

    def func(name, age = 18):
        print("%s:%s" %(name,age))
    
    # 指定参数
    func('eric', 28)
    # 使用默认参数
    func('john')
    
    # 执行结果
    eric:28
    john:18
    # 注:默认参数需要放在参数列表最后

    动态参数

    def func(*args) 接受多个参数,内部自动构造元组,序列前加*,避免内部构造元组
    def func(**kwargs) 接收多个参数,内部自动构造字典,序列前加**,直接传递字典
    def func(*args,**kwargs):接受多个参数,既可以自动构造元组,又可以自动构造字典。

    下面展示自动构造元组,自动构造字典及前两者综合的参数传递方式:

    def func(*args):
        print(args)
    
    a = [1, 2, 3]
    func(a)
    func(*a)
    # 执行结果:
    ([1, 2, 3],)
    (1, 2, 3)
    
    #################################
    
    def func(**kwargs):
        print(kwargs)
    
    func(name='john')
    # 执行结果:
    {'name': 'john'}
    
    func(name='john', aeg=18)
    dic = {'name': 'alex', 'age': 88}
    func(**dic)
    # 执行结果:
    {'name': 'alex', 'age': 88}
    
    
    ################################
    
    def func(*args,**kwargs):
        print(args)
        print(kwargs)
    
    func(1, 2, 3, 4)
    # 执行结果:
    (1, 2, 3, 4)
    {}
    
    
    func(k1=800, k2=900)
    # 执行结果:
    ()
    {'k1': 800, 'k2': 900}
    
    
    func(1, 2, 3, 4, k1=800, k2=900)
    # 执行结果:
    (1, 2, 3, 4)
    {'k1': 800, 'k2': 900}
    import smtplib
    from email.mime.text import MIMEText
    from email.utils import formataddr
      
      
    msg = MIMEText('邮件内容', 'plain', 'utf-8')
    msg['From'] = formataddr(["发件人名字",'shuaige@126.com'])
    msg['To'] = formataddr(["收件人名字",'shuainan@qq.com'])
    msg['Subject'] = "主题"
      
    server = smtplib.SMTP("smtp.126.com", 25)
    server.login("shuaige@126.com", "邮箱密码")
    server.sendmail('shuaige@126.com', ['shuainan@qq.com',], msg.as_string())
    server.quit()
    发送邮件的代码

    4.全局变量大写 局部变量小写

    补充:全局变量和局部变量关系

    # 全局变量
    PERSON = "alex"
    
    def func1():
        # 局部变量
        a = 123
        global PERSON
        PERSON = "eric"
        print(a)
    
    def func2():
        # 局部变量
        a = 456
        print(PERSON)
        print(a)
    
    func1()
    func2()

    函数补充内容

    Filter函数的一种实现

    def MyFilter(func, seq):
        # func,函数名, 函数名() ====》 执行
        # seq
        result = []
        for i in seq:
            # func = f1()
            # func(x) 执行f1 函数,并获取返回值,将其赋值ret
            ret = func(i)
            if ret:
                result.append(i)
        return result
    
    
    def f1(x):
        if x > 22:
            return True
        else:
            return False
    
    r = MyFilter(f1, [11,22,33,44,55])
    print(r)

    Map函数的一种实现

    li = [11,22,33,44]
    def x(arg):
        return arg + 100
    
    def MyMap(func, arg):
        # func 函数
        # arg 列表
        result = []
        for i in arg:
            ret = func(i)
            result.append(ret)
        return result
    r = MyMap(x, li)
    print(r)

    作业及答案:

    利用函数写一个登录功能

    实现用户登录 添加用户 修改用户 删除用户等功能

    登录函数写法
    
    def login(username, password):
        """
        用于用户名密码的验证
        :param username: 用户名
        :param password: 密码
        :return: True:用户名验证成功;False:用户验证失败。
        """
        # f = open("db","r",encoding='utf-8')
        with open("db", "r", encoding="utf-8") as f:
            for line in f:
                # 默认strip无参数:去除空格,换行符
                # 有参数:移出两侧指定的值
                line = line.strip()
                line_list = line.split(":")
                if username == line_list[0] and password == line_list[1]:
                    return True
    
            return False
    
    
    def user_exist(username):
        """
        检查用户名是否存在
        :param username: 要检测到用户名
        :return: True,已存在;False,不存在
        """
        # 一行一行查找,如果用户名存在,return True
        with open("db", "r", encoding="utf-8") as f:
            for line in f:
                line = line.strip()
                line_list = line.split(":")
                if line_list[0] == username:
                    return True
    
    def register(username, password):
        """
        注册用户
        :param username: 用户名
        :param password: 密码
        :return: True,注册成功
        """
        with open("db", "a", encoding="utf-8") as f:
            temp = "
    " + username + ":" + password
            f.write(temp)
        return True
    
    
    def main():
        print("Welcome to our sysrem !")
        inp = input("1.登录;2.注册")
    
        user = input("请输入用户:")
        pwd = input("请输入密码:")
    
        if inp == "1":
            is_login = login(user, pwd)
            if is_login:
                print("登录成功")
            else:
                print("登录失败")
    
        elif inp == "2":
            is_exist = user_exist(user)
            if is_exist:
                print("用户名已存在,无法注册 !")
            else:
                result = register(user,pwd)
                if result:
                    print("注册成功")
                else:
                    print("注册失败")
    
    
    if __name__ == '__main__':main()
  • 相关阅读:
    【数据结构】算法 Tree Sub Structure 树的子结构
    【数据结构】算法 Binary Search Tree find Kth largest Node 二叉搜索树的第k大节点
    【数据结构】算法 Count Complete Tree Nodes 完全二叉树的节点个数
    【数据结构】算法 合并K个有序链表Merge k Sorted Lists
    JVisualVM 插件安装中出现网络问题
    [ISSUE] Logback TimeBasedRollingPolicy not rolling every day.
    【数据结构】算法 计算数组中的逆序对
    JQ为元素添加class
    时间戳转换成日期
    JS拖拽
  • 原文地址:https://www.cnblogs.com/yaohan/p/5470924.html
Copyright © 2011-2022 走看看