本篇主要内容:深浅拷贝,自定义函数,三目运算,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']} # 深拷贝
>>>

三目运算

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

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 = "\n" + username + ":" + password
f.write(temp)
return True def main():
print("Welcome to our sysrem !")
inp = input("1.登录;2.注册") user = input("请输入用户:")
pwd = input("请输入密码:") if inp == "":
is_login = login(user, pwd)
if is_login:
print("登录成功")
else:
print("登录失败") elif inp == "":
is_exist = user_exist(user)
if is_exist:
print("用户名已存在,无法注册 !")
else:
result = register(user,pwd)
if result:
print("注册成功")
else:
print("注册失败") if __name__ == '__main__':main()

[Python笔记]第三篇:深浅拷贝、函数的更多相关文章

  1. python基础(三元运算+深浅拷贝+函数参数)

    三元运算 三元运算,又称三目运算,主要作用是减少代码量,是对简单的条件语句的缩写. 书写格式: result = 值1 if 条件 else 值2 即如果条件成立,则将值1赋给result变量,如果不 ...

  2. python 【第三篇】:函数及参数

    函数背景 在学习函数之前,一直遵循:面向过程编程: 根据业务逻辑从上到下实现功能,其往往用一长段代码来实现指定功能,开发过程中最常见的操作就是粘贴复制,也就是将之前实现的代码块复制到现需功能处,如下: ...

  3. [Python笔记]第四篇:内置函数

    本篇主要内容:内置函数 函数 参考:https://docs.python.org/3.5/library/functions.html 内置函数列表 一.数学运算类 abs(x)求绝对值 >& ...

  4. 【python之路15】深浅拷贝及函数

    一.集合数据类型(set):无序不重复的集合,交集.并集等功能 二.三元运算符 三.深浅拷贝 1)字符串和数字:深浅内存地址都一样 2)其他:浅拷贝:仅复制最外面第一层 深拷贝:除了最内层其他均拷贝 ...

  5. python之set集合、深浅拷贝

    一.基本数据类型补充 1,关于int和str在之前的学习中已经介绍了80%以上了,现在再补充一个字符串的基本操作: li = ['李嘉诚','何炅','海峰','刘嘉玲'] s = "_&q ...

  6. python之set集合及深浅拷贝

    一.知识点补充 1.1字符串的基本操作 li =["李李嘉诚", "麻花藤", "⻩黄海海峰", "刘嘉玲"] s = ...

  7. Scala语言笔记 - 第三篇(容器方法篇)

    Scala语言笔记 - 第三篇(容器方法篇) 目录 Scala语言笔记 - 第三篇(容器方法篇) map和flapMap方法: ​ 最近研究了下scala语言,这个语言最强大的就是它强大的函数式编程( ...

  8. Python开发【第三篇】:函数&读写文件

    三元运算 三元运算,是条件语句的简单的写法.如果条件为真,则返回值1,否则,返回值2. ret = 值1 if 条件 else 值2 深浅拷贝 对于数字(int)和字符串(str)而言,赋值.深拷贝. ...

  9. python基础(7)--深浅拷贝、函数

    1.深浅拷贝 在Python中将一个变量的值传递给另外一个变量通常有三种:赋值.浅拷贝.深拷贝 Python数据类型可氛围基本数据类型包括整型.字符串.布尔及None等,还有一种由基本数据类型作为最基 ...

随机推荐

  1. ie中弹出框中元素的定位

    用selenium在ie8浏览器中定位一个弹出框时,直接用ie developer tools可能不一定能定位到,有一个解决的办法是直接在url后面加上#noHide,刷新后,然后再用ie devel ...

  2. centos升级openssh的两种方式

    此文介绍的是服务器在有网络和无网络情况下升级openssh方式. 一.首先介绍一个无网络如何升级: 1.准备相关的包 openssh下载地址:  http://mirror.internode.on. ...

  3. 什么是左值(what is a lvalue)?

    引用并翻译自<C++ premier plus> 左值是可以通过地址引用的数据对象(data object),例如,变量,数组的元素,结构体的成员,引用变量,以及复引用的指针(defere ...

  4. Mac下Intellij IDea发布Java Web项目详解三 新建Module

    准备工作1:新建第一个JavaWeb项目 Step4 添加两个module 4.1 右键[WebWorkSpace]-[New]-[Module] 4.2 重复 准备工作1:新建第一个JavaWeb项 ...

  5. hdu 4424 & zoj 3659 Conquer a New Region (并查集 + 贪心)

    Conquer a New Region Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...

  6. XP的定时关机命令?

    Windows XP的关机是由Shutdown.exe程序来控制的,位于Windows/System32文件夹中.如 果想让Windows 2000也实现相同的效果,能够把Shutdown.exe拷贝 ...

  7. [Javascrip] Logging Timing Data to the Console

    Learn to use console.time with console.timeEnd to get accurate timings of operations in javascript. ...

  8. java.util.jar.JarFile cause native heap memory leak

    最近项目中使用了JarFile 这个类 来load jar包中的 configuration,大致的情况如下 public void processJarEntries(JarFile paramJa ...

  9. Unix文件操作

    一.概述 Unix文件操作常用函数包括open.close.creat.lseek.dup.dup2.fcntl等, 其中open.creat. fcntl函数需要包含头文件<fcntl.h&g ...

  10. 安卓扫码:简单的ZXing使用记录

    ZXing是Google提供的条形码.二维码等的生成.解析的库.最近工作需求去研究了一下,主要是研究怎么扫描二维码(QRCode).网上教程也不少,但大多看了不明所以,甚至看了半天都不知道解码到底从哪 ...