本篇主要内容:深浅拷贝,自定义函数,三目运算,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. android EditText监听事件及参数详解

    editText.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence ...

  2. cocos2d的框架思路

    这是我第一次写cocos的框架思路哈,虽然只是写完了一个程序,按理来说应该再多写一些,多积累一些经验了再来写这个框架的构成,但是我觉得还是把我这次写代码的所有想法先记下来哈,等到以后继续写cocos的 ...

  3. 《编写高质量代码——Web前端开发修炼之道》读后随笔

    结构样式行为的分离 结构标准包括XML标准.XHTML标准.HTML标准:样式标准有CSS标准:行为标准主要包括DOM标准和ECMAScript标准. 通常的项目会按照如上的方式进行分离,但自己曾今做 ...

  4. 80X86 分段机制(读书笔记)

    GDT(全局描述符表)本身并不是一个段,而是线性地址空间的一个数据结构.GDT的线性地址和长度必须加载进GDTR寄存器中.LDT(局部描述符表)存放在LDT类型的系统段中.此时GDT必须含有LDT的段 ...

  5. serialVersionUID的作用以及设置方法(转)

    声明:本篇文章是转载的 http://blog.csdn.net/kakaxi_77/article/details/8129070 http://snowlotus.iteye.com/blog/2 ...

  6. .mtl文件格式解析

    最近在导入下载的.OBJ文件,有时会出现只有模型而没有材质渲染的情况.难道材质要自己一点一点重新赋予?抓狂……我知道.OBJ文件用来存储模型信息,观察第一行代码,可以看到材质库文件为mtllib ## ...

  7. 第一个 Python 程序 - Email Manager Demo

    看了一些基础的 Python 新手教程后,深深感觉到 Python 的简洁与强大,这是我的第一个 Python Demo.下面是完整代码与执行截图. 代码: # encoding: utf-8 ''' ...

  8. [转] socket异步编程--libevent的使用

    这篇文章介绍下libevent在socket异步编程中的应用.在一些对性能要求较高的网络应用程序中,为了防止程序阻塞在socket I/O操作上造成程序性能的下降,需要使用异步编程,即程序准备好读写的 ...

  9. Ouath协议

    OAuth是一个开放协议,允许用户让第三方应用以安全且标准的方式获取该用户在某一网站.移动或桌面应用上存储的私密的资源(如用户个人信息.照片.视频.联系人列表),而无需将用户名和密码提供给第三方应用. ...

  10. QT pro文件解析

    在QT中使用qmake自动生成pro文件,如果要自己定制工程选项,则需要自行修改pro文件. pro文件有以下关键字:TEMPLATE.TARGET.DESTDIR.DEPENDPATH.INCLUD ...