三元运算
三元运算(三目运算),是对简单的条件语句的缩写。
result = 值 1 if 条件 else 值 2 # 如果条件成立,那么将 “值1” 赋值给result变量,否则,将“值2”赋值给result变量 |
深浅拷贝
一、数字和字符串
对于数字和字符串而言,赋值、浅拷贝和深拷贝无意义,因为其永远指向同一个内存地址。
import copy # ######### 数字、字符串 ######### n1 = 123 # n1 = "i am alex age 10"print ( id (n1)) # >>>1876955408 # ## 赋值 ## n2 = n1 print ( id (n2)) # >>>1876955408 # ## 浅拷贝 ## n2 = copy.copy(n1) print ( id (n2)) # >>>1876955408 # ## 深拷贝 ## n3 = copy.deepcopy(n1) print ( id (n3)) # >>>1876955408 内存地址始终不变 |
二、其他基本数据类型
对于字典、元祖、列表 而言,进行赋值、浅拷贝和深拷贝时,其内存地址的变化是不同的。
1、赋值
赋值,只是创建一个变量,该变量指向原来内存地址,如:
n1 = { "k1" : "wu" , "k2" : 123 , "k3" : [ "alex" , 678 ]} n2 = n1 |
2、浅拷贝
浅拷贝,在内存中只额外创建第一层数据
import copy n1 = { "k1" : "wu" , "k2" : 123 , "k3" : [ "alex" , 678 ]} n3 = copy.copy(n1) |
3、深拷贝
深拷贝,在内存中将所有的数据重新创建一份(排除最后一层,即:python内部对字符串和数字的优化)
import copy n1 = { "k1" : "wu" , "k2" : 123 , "k3" : [ "alex" , 678 ]} n4 = copy.deepcopy(n1) |
函数(python是自上而下执行,先定义后引用)
函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可
函数式编程最重要的是增强代码的重用性和可读性
面向对象:对函数进行分类和封装,让开发“更快更好更强...”
一、定义和使用
def 函数名(参数): ... 函数体 ... 返回值 |
函数的定义主要有如下要点:
def:表示函数的关键字
函数名:函数的名称,日后根据函数名调用函数
函数体:函数中进行一系列的逻辑计算,如:发送邮件、计算出 [11,22,38,888,2]中的最大数等...
参数:为函数体提供数据
返回值:当函数执行完毕后,可以给调用者返回数据。
1、返回值
函数是一个功能块,该功能到底执行成功与否,需要通过返回值来告知调用者;
一旦执行return,函数就结束了;
函数的默认返回值为 None (就是没有写 return )。
2、参数
函数的有三中不同的参数:
普通参数(严格按照顺序。将实际参数赋值给形式参数)
默认参数(必须放置在参数列表的最后);指定参数(将实参赋值给形参)
动态参数:* 与 **
* #默认将传入的参数,全部放置在元组中 >>> def f1(*args): ... print(args,type(args)) ... >>> li = [11, 22, 'nimei']#定义一个列表 >>> f1(li) ([11, 22, 'nimei'],) <class 'tuple'>#把列表当成一个参数 >>> f1(*li) #参数前面又加一个*星号 (11, 22, 'nimei') <class 'tuple'>#列表里的每个元素都是一个参数 >>> str = "alex" >>> f1(str) #来看看字符串 ('alex',) <class 'tuple'> >>> f1(*str) #把字符串也拆分了 ('a', 'l', 'e', 'x') <class 'tuple'> #加*,相当于里面加了一层for循环 >>> #也可以说是把每个元素直接赋值给变量 |
** #默认将传入的参数,全部放置在字典中 >>> def f2(**args): ... print(args,type(args)) ... >>> f2(k1="v1",k2="v2") #参数输入必须是此种k,v类型 {'k2': 'v2', 'k1': 'v1'} <class 'dict'> >>> dict1 = {"k1":"v1","k2":"v2"} >>> f2(**dict1) #又加俩**,相当于把整个字典给赋值了 {'k2': 'v2', 'k1': 'v1'} <class 'dict'> >>> |
万能参数:*args,**kwargs >>> def f3(*args, **kwargs):#一星放前面,俩星放后面(规定) ... print(args) ... print(kwargs) ... >>> f3(11,22,k1="v1",k2="v1")#k,v类型参数最后传入 (11, 22) {'k2': 'v1', 'k1': 'v1'} >>> str.format()函数就是用的万能参数 def format(*args, **kwargs): # real signature unknown """ Return value.__format__(format_spec)
format_spec defaults to the empty string """ pass |
函数补充
1、同名函数,下面的会覆盖上面的
2、一个面试题:
函数的参数进行传递的时候,传的是引用,还是重新复制一份值呢??
>>> def f1(a1):
... a1.append(999)
...
>>> li = [11,22,33,44]
>>> ----------华丽分割线----------
>>> f1(li)
>>> print(li) #查看 li 是否被修改
[11, 22, 33, 44, 999]#说明python参数传递的是引用(就是内存地址)
>>>如果将分割线下面f1(li)赋值给li,会是什么效果呢:
>>> li = f1(li)
>>> print(li) 就是None,因为函数的默认返回值是None!!
3、变量:优先使用自己作用域内(也就是局部变量),没有再去其父类查找
全局变量(全部大写):在所有的作用域都可读
修改全局变量:变量前加 global
对于列表、字典等特殊变量:可以修改(如append()),但不可以重新赋值
内置函数
注:查看详细猛击这里
open函数,该函数用于文件处理
操作文件时,一般需要经历如下步骤:
打开文件
操作文件
一、打开文件
文件句柄 = open('文件路径', '模式') |
打开文件时,需要指定文件路径和打开方式,打开后,即可获取该文件句柄,日后通过此文件句柄对该文件操作。
打开文件的模式有:
r ,只读模式【默认】
w,只写模式【不可读;不存在则创建;存在则清空内容】
x, 只写模式【不可读;不存在则创建,存在则报错】
a, 追加模式【可读; 不存在则创建;存在则只追加内容】
"+" 表示可以同时读写某个文件;"b"表示以字节的方式操作
r+ | rb : 可以调整位置修改,最常用
w+ | wb : 先清空才能读,不好
a+ | ab : seek()无法调节位置,始终是在最后追加
注:以b方式打开时,读取到的内容是字节类型,写入时也需要提供字节类型
#硬盘保存的是二进制文件,而python读取的却是str字符串类型文件,所以说,这中间存在一个二进制转换字符串的过程,是python自动转换的;除非显式的告诉python需要手动转换,即加个b:
f = open('db', 'ab') f.write(bytes("你妹", encoding="utf-8")) # 有b,需要将字符串转换成二进制,然后标明其编码格式;编码是在bytes()里面标注的 f.close() |
f.seek(index)
#修改指针位置,然后写文件的时候就是从修改之后的index(字节的位置)的位置向后覆盖写文件
f.tell() #获取当前指针的位置(字节)
所以,一般修改指针的位置的时候,都是先获取位置,然后修改,即:
f.seek(f.tell()) #当然,获取位置之前的操作,可以是设置位置,一段代码如下:
f = open("db", "r+", encodong="utf-8") #打开模式无b,则read,按照字符读取 data = f.read(1) #读取第一个字符的位置 print(f.tell()) # 3,因为一个字符是三个字节 f.seek(f.tell()) #调整当前指针位置 f.write("888") #当前指针位置开始向后覆盖 f.close() |
二、操作文件
read()#无参数,读全部,有参数(b,按字节;无b,按字符) tell()#获取当前指针位置(字节) seek()#指针跳转到指定位置(字节) write()#写数据:有b,按字节;无b,按字符 close()#文件关闭 fileno()#文件描述符,socket时会用 flush()#强制刷新,将缓冲区的信息写到文件里 readline()#仅读取一行 truncate()#截断,把当前指针位置后面的字符清空 for循环文件对象 f = open(xxx) for line in f: print(line) |
三、管理上下文
为了避免打开文件后忘记关闭,可以通过管理上下文,即:
with open ( 'log' , 'r' ) as f: ... |
如此方式,当with代码块执行完毕时,内部会自动关闭并释放文件资源。
在Python 2.7 及以后,with又支持同时对多个文件的上下文进行管理,即:
with open ( 'log1', 'r' ) as obj1, open ( 'log2', 'w' ) as obj2: pass #可以将第一个文件的内容写到第二个文件里 |
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 ###################### my_lambda = lambda arg: arg + 1 result = my_lambda( 123 ) |
递归
利用函数编写如下数列:
斐波那契数列指的是这样一个数列 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 func(arg1,arg2): if arg1 = = 0 : print ( arg1, arg2 ) arg3 = arg1 + arg2 print ( arg3) func(arg2, arg3)
|