首页 > 代码库 > PYTHON_DAY3

PYTHON_DAY3

目录

一、字符编码

  a.了解字符编码
  b.什么是字符编码
  c.文本编辑器
  d.程序的执行

二、文件处理

  1.文件处理流程
  2.文件打开模式
  3.文件内光标移动
  4.上下文管理

三、函数

  1、数学定义的函数与python中的函数
  2、为何使用函数
  3、函数和过程
  4、函数参数
  5、函数的返回值
  6、自定义函数  
  7、调用函数

一、字符编码

a.了解字符编码    
  
 1. 文本编辑器存取文件的原理(nodepad++,pycharm,word)
   打开编辑器就打开了启动了一个进程,是在内存中的,所以在编辑器编写的内容也都是存放与内存中的,断电后数据丢失
   因而需要保存到硬盘上,点击保存按钮,就从内存中把数据刷到了硬盘上。
在这一点上,我们编写一个py文件(没有执行),跟编写其他文件没有任何区别,都只是在编写一堆字符而已。

2. python解释器执行py文件的原理 ,例如python test.py
   第一阶段:python解释器启动,此时就相当于启动了一个文本编辑器
   第二阶段:python解释器相当于文本编辑器,去打开test.py文件,从硬盘上将test.py的文件内容读入到内存中
   第三阶段:python解释器解释执行刚刚加载到内存中test.py的代码
  
 总结:
   python解释器是解释执行文件内容的,因而python解释器具备读py文件的功能,这一点与文本编辑器一样
   与文本编辑器不一样的地方在于,python解释器不仅可以读文件内容,还可以执行文件内容。

b.什么是字符编码

计算机要想工作必须通电, 也就是说‘电’驱使计算机干活, 而‘电’的特性,就是高低电平(高低平即二进制数1, 低电平即二进制数0), 也就是说计算机只认识数字
  编程的目的是让计算机干活,而编程的结果说白了只是一堆字符,也就是说我们编程最终要实现的是:一堆字符驱动计算机干活(我们输入计算机能读懂的语言来操作计算机干活)
 所以必须经过一个过程:
    字符 - -------(翻译过程)------->数字
    这个过程实际就是一个字符如何对应一个特定数字的标准,这个标准称之为字符编码

c.文本编辑器

无论是何种编辑器,要防止文件出现乱码(请一定注意,存放一段代码的文件也仅仅只是一个普通文件而已,此处指的是文件没有执行前,我们打开文件时出现的乱码)
核心法则就是,文件以什么编码保存的,就以什么编码方式打开(否则生成乱码)

d.程序的执行
阶段一:启动python解释器

阶段二:python解释器此时就是一个文本编辑器,负责打开文件test.py,即从硬盘中读取test.py的内容到内存中

此时,python解释器会读取test.py的第一行内容,#coding:utf-8,来决定以什么编码格式来读入内存,这一行就是来设定python解释器这个软件的编码使用的编码格式这个编码,
可以用sys.getdefaultencoding()查看,如果不在python文件指定头信息#-*-coding:utf-8-*-,那就使用默认的
python2中默认使用ascii,python3中默认使用utf-8

阶段三:读取已经加载到内存的代码(unicode编码的二进制),然后执行,执行过程中可能会开辟新的内存空间,比如x="egon"
内存的编码使用unicode,不代表内存中全都是unicode编码的二进制,在程序执行之前,内存中确实都是unicode编码的二进制,比如从文件中读取了一行x="egon",其中的x,等号,引号,地位都一样,都是普通字符而已,都是以unicode编码的二进制形式存放与内存中的
但是程序在执行过

二、文件处理 

1.文件处理流程:

--打开文件,得到文件句柄并赋值给一个变量
--通过句柄对文件进行操作
--关闭文件
f = open(‘chenli.txt‘)  # 打开文件
first_line = f.readline()
print(‘first line:‘, first_line)  # 读一行
print(‘我是分隔线‘.center(50, ‘-‘))
data = http://www.mamicode.com/f.read()  # 读取剩下的所有内容,文件大时不要用>

  


2.文件打开模式

文件句柄 = open(‘文件路径‘,‘模式‘)

打开文件时,需要指定文件路径和以何等方式打开文件,打开后,即可获取该文件句柄,日后通过此文件句柄对该文件操作。

打开文件的模式有:

r ,只读模式【默认模式,文件必须存在,不存在则抛出异常】
w,只写模式【不可读;不存在则创建;存在则清空内容】
x, 只写模式【不可读;不存在则创建,存在则报错】
a, 追加模式【可读; 不存在则创建;存在则只追加内容】
"+" 表示可以同时读写某个文件

r+, 读写【可读,可写】
w+,写读【可读,可写】
x+ ,写读【可读,可写】
a+, 写读【可读,可写】
"b"表示以字节的方式操作

rb 或 r+b
wb 或 w+b
xb 或 w+b
ab 或 a+b
注:以b方式打开时,读取到的内容是字节类型,写入时也需要提供字节类型,不能指定编码


3.文件内光标移动

with open(‘a.txt‘,‘r‘,encoding=‘utf-8‘) as f:
print(f.read(4)) # 数字指的是读取4个字符

with open(‘a.txt‘,‘r‘,encoding=‘utf-8‘) as f:
f.seek(3) # seek内指定的数字代表读取3个字节
print(f.tell()) # 当前光标所在的位置
print(f.read())

with open(‘b.txt‘,‘rb‘) as f:
f.read()
f.seek(3) #默认情况,是以文件起始位置作为开始,往后移动3个bytes
f.read(1)
print(f.tell())
f.seek(2,1) #1 代表以当前光标所在的位置为开始,往后移动2个 bytes


4.上下文管理

以with方式打开文件,不需要写关闭语句f.close() ,而且with可以打开多个文件

f=open(‘a.txt‘,‘w‘)
f.write(‘111111\n‘)
f.close() # 常常容易忘记写关闭

with open(‘a.txt‘,‘r‘,encoding=‘utf-8‘) as f,open(‘b.txt‘) as b_f:
print(f.read())
print(‘====>‘)

三、函数

1、数学定义的函数与python中的函数 
 
  数学定义函数:一般的,在一个变化过程中,假设有两个变量x、y,如果对于任意一个x都有唯一确定的一个y和它对应,
  那么就称x是自变量,y是x的函数。x的取值范围叫做这个函数的定义域,相应y的取值范围叫做函数的值域。

例如: y = 2x

PYTHON定义函数:函数是逻辑结构化和过程化的一种编程方法。
python中函数定义方法:
def test(x):
    "The function definitions "
    x += 1
    return x

def:定义函数的关键字
test:函数名
():括号内可定义形参
"":文档描述(非必要,但强烈建议为你的函数添加描述信息)
x += 1:泛指代码块或程序处理逻辑
return:定义返回值

  

补充:
编程语言中的函数与数学意义的函数是截然不同的俩个概念,编程语言中的函数是通过一个函数名封装好一串用来完成某一特定功能的逻辑,
数学定义的函数就是一个等式,等式在传入因变量值x不同会得到一个结果y,这一点与编程语言中类似(也是传入一个参数,得到一个返回值),
不同的是数学意义的函数,传入值相同,得到的结果必然相同且没有任何变量的修改(不修改状态),而编程语言中的函数传入的参数相同返回值可
不一定相同且可以修改其他的全局变量值(因为一个函数a的执行可能依赖于另外一个函数b的结果,b可能得到不同结果,那即便是你给a传入相同
的参数,那么a得到的结果也肯定不同)

2、为何使用函数

a.代码重复过多,一个劲的copy and paste不符合高端程序员的气质
b.如果日后需要修改发邮件的这段代码,比如加入群发功能,那你就需要在所有用到这段代码的地方都修改一遍

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

 

总结使用函数的好处: 
  1.代码重用

  2.保持一致性,易维护

  3.可扩展性


3、函数和过程

过程定义:过程就是简单特殊没有返回值的函数

这么看来我们在讨论为何使用函数的的时候引入的函数,都没有返回值,没有返回值就是过程,没错,但是在python中有比较神奇的事情

 

def test01():
    msg=‘hello The little green frog‘
    print msg
 
def test02():
    msg=‘hello WuDaLang‘
    print msg
    return msg
 
 
t1=test01()
 
t2=test02()
 
 
print ‘from test01 return is [%s]‘ %t1
print ‘from test02 return is [%s]‘ %t2

  

总结:当一个函数/过程没有使用return显示的定义返回值时,python解释器会隐式的返回None,

所以在python中即便是过程也可以算作函数。
def test01():
    pass
 
def test02():
    return 0
 
def test03():
    return 0,10,‘hello‘,[‘alex‘,‘lb‘],{‘WuDaLang‘:‘lb‘}
 
t1=test01()
t2=test02()
t3=test03()
 
 
print ‘from test01 return is [%s]: ‘ %type(t1),t1
print ‘from test02 return is [%s]: ‘ %type(t2),t2
print ‘from test03 return is [%s]: ‘ %type(t3),t3

  

总结:

返回值数=0:返回None

返回值数=1:返回object

返回值数>1:返回tuple

4、函数参数

从大的角度去看,函数的参数分两种:
                  形参(变量名)
                  实参(值)

技术分享



(形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。形参只在函数内部有效。函数调用结束返回主调用函数后则不能再使用该形参变量)

(实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。应预先用赋值,输入等办法使参数获得确定值)
详细的区分函数的参数分为五种:

# 位置参数

# def foo(x,y,z):   #位置形参:必须被传值的参数
#     print(x,y,z)
#
# 
# foo(1,2,3)        #位置实参数:与形参一一对应

 

# 关键字参数:key=value

def foo(x,y,z):
    print(x,y,z)

foo(z=3,x=1,y=2)
# foo(1,z=3,y=2) #正确
# foo(x=1,2,z=3) #错误
# foo(1,x=1,y=2,z=3)#错误 x对应value重复

 

关键字参数需要注意的问题:

 1:关键字实参必须在位置实参后面

2: 不能重复对一个形参数传值

 

# 默认参数

当共同实参相同时,就在形参位置赋值value
def register(name,age,sex=‘male‘): #形参:默认参数
    print(name,age,sex)

register(‘asb‘,age=40)
register(‘a1sb‘,39)
register(‘a2sb‘,30)
register(‘a3sb‘,29)

 

默认参数需要注意的问题:

  1:默认参数必须跟在非默认参数后
    def register(sex=‘male‘,name,age): #在定义阶段就会报错
   print(name,age,sex)

  2:默认参数在定义阶段就已经赋值了,而且只在定义阶段赋值一次
    a=100000000
  def foo(x,y=a):
  print(x,y)
    a=0
  foo(1)

  3:默认参数的值通常定义成不可变类型

 

# 可变长参数
def foo(x,y,*args): # *会把溢出的按位置定义的实参都接收,以元组的形式赋值给args
    print(x,y)
    print(args)

foo(1,2,3,4,5)


def add(*args):
    res=0
    for i in args:
        res+=i
    return res
print(add(1,2,3,4))
print(add(1,2))




def foo(x, y, **kwargs):  # **会把溢出的按关键字定义的实参都接收,以字典的形式赋值给kwargs
    print(x, y)
    print(kwargs)
foo(1,2,a=1,name=‘egon‘,age=18)

def foo(name,age,**kwargs):
    print(name,age)
    if ‘sex‘ in kwargs:
        print(kwargs[‘sex‘])
    if ‘height‘ in kwargs:
        print(kwargs[‘height‘])

foo(‘egon‘,18,sex=‘male‘,height=‘185‘)
foo(‘egon‘,18,sex=‘male‘)

 

# 命名关键字参数(了解)
def foo(name,age=10,*args,sex=‘male‘,height,**kwargs):
    print(name)
    print(age)
    print(args)
    print(sex)
    print(height)
    print(kwargs)

foo(‘alex‘,1,2,3,4,5,sex=‘female‘,height=‘150‘,a=1,b=2,c=3,)


def foo(x,y,z):
    print(x,y,z)

# foo(*[1,2,3]) #foo(1,2,3)
foo(*[1,2]) #foo(1,2)

def foo(*args):
    print(args)

foo(*[‘A‘,‘B‘,‘C‘,‘D‘]) # 1,2,3,4 <=====>*(1,2,3,4)



def foo(**kwargs):
    print(kwargs)

#x=1,y=2  <====>**{‘y‘: 2, ‘x‘: 1}
# foo(x=1,y=2)

foo(**{‘y‘: 2, ‘x‘: 1,‘a‘:1}) #foo(a=1,y=2,x=1)

def foo(x,y,z):
    print(x,y,z)

# foo(**{‘z‘:3,‘x‘:1,‘y‘:2}) #foo(x=1,z=3,y=2)
foo(**{‘z‘:3,‘x‘:1}) #foo(x=1,z=3)


def foo(x,y,z):
    print(‘from foo‘,x,y,z)

def wrapper(*args,**kwargs):
    print(args)
    print(kwargs)


wrapper(1,2,3,a=1,b=2)



def foo(x,y,z):
    print(‘from foo‘,x,y,z)
def wrapper(*args,**kwargs):
    print(args) #args=(1,2,3)
    print(kwargs) #kwargs={‘a‘:1,‘b‘:2}
    foo(*args,**kwargs) #foo(*(1,2,3),**{‘a‘:1,‘b‘:2}) #foo(1,2,3,b=2,a=1)
# wrapper(1,2,3,a=1,b=2)
wrapper(1,z=2,y=3)



def foo(x,y,z):
    print(‘from foo‘,x,y,z)
def wrapper(*args,**kwargs):
    # print(args) #args=(1,)
    # print(kwargs) #kwargs={‘y‘:3,‘z‘:2}
    foo(*args,**kwargs) #foo(*(1,),**{‘y‘:3,‘z‘:2}) #foo(1,z=2,y=3)
# wrapper(1,2,3,a=1,b=2)
wrapper(1,z=2,y=3)

  

5、函数的返回值
def foo():
    print(‘from foo‘)
    return None
res=foo()
print(res)

‘‘‘
以下三种情况返回值都为None:
    1.没有return
    2.return 什么都不写
    3.return None

‘‘‘

#return 一个值  函数调用返回的结果就是这个值
def foo():
    print(‘from foo‘)
    x=1
    return x
res=foo()
print(res)




#return 值1,值2,值3,...   返回结果:(值1,值2,值3,...)
def foo():
    print(‘from foo‘)
    x=1
    return 1,[2,3],(4,5),{}
res=foo()
print(res) #打印结果:(1,[2,3],(4,5),{})
a,b,c,d=foo()
print(d)

  

6、自定义函数

#为什么要定义函数?:先定义后使用,如果没有定义而直接使用,就相当于引用了一个不存在的变量名
foo()
def foo():
print(‘from foo‘)
print(foo)

# 函数的使用包含两个阶段:定义阶段 和 使用阶段

语法
def 函数名(参数1,参数2,...):
"""文档注释"""
函数体
return 值

x=len(‘hello‘)
print(x)

# 定义函数的三种形式

  a:无参数函数:

  
如果函数的功能仅仅只是执行一些操作而已,就定义成无参函数,无参函数通常都有返回值
  def print_star():
  print(‘#‘*6)

  b:定义有参函数:

  
函数的功能的执行依赖于外部传入的参数,有参函数通常都有返回值
  def my_max(x,y):
  res=x if x >y else y
  return res


三元表达式
x=10
y=2
if x > y:
    print(x)
else:
    print(y)

res=x if x > y else y
print(res)

  


c:空函数

def auth():
"""认证功能"""
pass
auth()

def insert():
"""插入功能"""
pass
def select():
"""查询功能"""
pass
def delete():
"""删除功能"""
pass
def update():
"""更新功能"""


7、调用函数

# 按照有参和无参可以将函数调用分两种
def foo():
    print(‘from foo‘)

foo() #定义时无参,调用时也无需传入参数


def bar(name):
    print(‘bar===>‘,name)

bar(‘egon‘) #定义时有参,调用时也必须有参数

  


# 按照函数的调用形式和出现的位置,分三种:

1.
def my_max(x,y):
res=x if x >y else y  # 调用函数语句形式
    return res
2.
res=my_max(1,2)*10000000    # 调用函数表达式形式
print(res)

3.
res=my_max(my_max(10,20),30) # 把函数调用当中另外一个函数的参数
print(res)

PYTHON_DAY3