Fork me on GitHub

python函数-字典、参数传值、变量范围

img

本文主要介绍Python基本语法中的函数-字典、参数传值、变量范围.

变量

变量仅仅只是一个名称,并没有其他意义。

函数复制给变量

1
2
3
4
5
6
7
f = max
>>> f
# <built-in function max>
>>> max
# <built-in function max>
f(1,2,3)
# 3
当然也可以将函数功能改变,如将常数赋予给函数
1
2
3
max = 7
>>> max
>>> 7

变量赋值

引用

1
2
3
4
a = 10
b = a
>>> b
>>> 10
在这个情况下,10这个值被指向变量a的地址,当将a赋给b时,实际上是a把地址赋给了b,a、b在同一个地址上,即a,b的id相同。牢记,Python中的赋值都是将变量指向值,而不是赋给内存。

可变类型

  1. 列表
  2. 字典

在字典中,key即键值只能为不可变类型,不能为可变类型,这是因为可变类型不符合哈希类型!!!

不可变类型

  1. 数字
  2. 字符串

    变量范围

局部变量

局部变量的修改不会改变全局变量的值

全局变量

1.在另一个函数内调用一个函数中定义的变量:使用全局变量

1
2
3
global_var = o
def get_var():
print(global_var + 1)

2.定义的一个全局变量在一个函数内改变其值

使用global关键词
1
2
3
4
global_var = 0
def change_var():
global global_var
global_var = 1
当列表作为全局变量时,可以不用global

函数

eval()

一个变量被转化成字符串,然后使用eval()函数还原到初始的变量类型

print

print()函数和help()函数都没有return返回值

print()函数可以设置输出的分隔符号和结束符:

1
2
print(1,2,3, sep='<',end=";")
# 1<2<3;
  • sep="" : 分隔符号设置
  • end="" : 结束符号设置

字符串函数

  • 字符串切割:split()
如果括号内不传递参数,则默认以不可见字符分割,如空格,\n,\t等。
  • 一切类型转换为字符串: str()

  • 判断某段字符是否在字符串内:str1 in str2

匿名函数

基本

作用:解耦(减少代码耦合度)

命名:lambda 参数:函数体

注意:lambda函数的函数体部分相当于自定义函数的return的内容。

调用格式: 变量名()

示例:

1
2
3
4
add = lambda x,y : x + y
result = add(1,1)
>>> result
>>> 2
在上一个例子中,可以发现匿名函数默认有return功能

拓展-匿名函数做函数参数

1
2
3
4
5
6
def func(a,b,f):
result = f(a,b)
print(result)

func(1,2,lambda x,y:x+y)
>>> 3

函数文档说明

1
2
3
4
5
6
def test():
"""
这是函数说明功能
"""

help(test)

函数参数

缺省参数

调用参数时,缺省参数的值如果没有传入,则被认为是默认值。

1
2
3
4
5
6
def info(name, age = 18):
print "name", name
print "age", age

info(name="keith")
ingfo(name="keith", age= 19)

不定参数

1.指定不定个数的参数:*args

1
2
def func(a,b, *args):
pass
*args会将超过设定的多余参数以元组的形式返回

2.**kwargs

1
2
def func(a,b,*args,**kwargs):
pass

作用:配合*args使用,将多余的参数可以进行一定的描述功能后,以字典的形式返回结果

1
2
3
4
5
6
7
8
def func(a,b,*args,**kwargs):
print(a)
print(b)
print(args)
print(kwargs)

func(11,22,num1=33,num2=44)
# 返回11,22,(),{'num1':33,'num2':44}
在多余的变量中,带有功能命名的变量会被传入kwargs中当作字典。剩下的放入args的元组中

拆包将剩余变量分别赋给*args , **kwargs

1
2
3
4
5
6
def func(a,b,*args,**kwargs):
pass

A = (33,44)
B = {"name":'keith'}
func(11,22,*A,**B)



递归

递归必须要给定递归的终止条件,否则就会内存溢出,例如在手机APP中有时会出现闪退的现象,可能就是内存溢出。

img


文件操作

打开文件

r,w,a,rb,wb,ab,r+,w+,a+,rb+,wb+,ab+

语法:f = open('text.txt', 'w') f.close()

写入文件

语法: f.write(content)

读取文件

基本方法

读取

语法:f.read(args)

参数args:一个数字,代表每次读取的内容个数,每执行一次读取命令,会从上一次读取到的位置继续读取。

  • f.readlines():把文件内每一行读取出来,将每一行转换为列表元素。
查找当前位置
1
2
position = f.tell()
# 返回当前文件的读取位置
定位到某个位置

语法:seek(offset, from)

  • offset:偏移量
  • from:读取方向,0表示文件开头,1表示当前位置,2表示文件末尾

异常情况–读取大文件

注意:当读取一个很大的文件时,应该分批次读取文件,不能直接使用read()一次性读取。

解决方法:

1
2
3
4
5
6
7
f = open("xxx.txt",'r')
# 使用循环分批次进行读取,注意添加停止条件
while True:
content = f.read(1024)
if len(content)==0:
break
f.close()

文件备份

错误写法:

1
2
3
4
5
6
7
8
f = open('text[复件].txt', 'w')
cp = open('text.txt', 'r')
content = cp.read()
f.write(content)
co = f.read()
print(co)
content.close()
f.close()

错误:用open打开一个文件,此时调用的是w写入模式,下面使用read是没有权限的,你得使用w+读写模式;另外,在使用write写入内容时,此时并没有真正的写入,而是还存在与内存中。此时执行read读取的为空字符。需要执行f.close()以后,再使用open(“xxx.txt”),f.read()才能够读取到数据。

正确做法:

1
2
3
4
5
6
7
8
9
10
f = open("demo[附件].txt", 'w+')
cp = open("demo.txt", 'r')
content = cp.read()
f.write(content)
cp.close()
f.close()
f1 = open("demo[附件].txt","r")
co = f1.read()
print(co)
f1.close()

os模块与文件操作

文件重命名

使用os模块:

1
2
3
4
5
import os
"""
os.rename('原名称文件','修改名文件')
"""
os.rename("xxx.txt"'test.txt')
文件删除

使用os模块

1
2
import os
os.remove("文件名")
创建文件夹
1
2
import os 
os.mkdir("repo")

删除文件夹


1
2
import os 
os.rmdir()
获取当前目录
1
2
3
import os 
# get current work directory
os.getcwd()
改变默认目录
1
2
import os
os.chdir("../")
获取目录列表
1
2
3
import os 
# 获取当前目录下的列表
os.listdir("./")

获取目录列表后,文件名被存放在列表中。


面向对象

魔法方法

1.__init__

  1. 创建一个对象
  2. python会自动调用init方法
  3. 返回创建对象的引用给TOM

一般用于初始化变量,可以当作类的变量列表,向创建的对象内添加变量

1
2
3
4
5
6
class Animal:
def __init__(self, name, age):
self.name = name
self.age = age

cat = Animal("kitty", 5)

2.__str__

可以获取对象描述信息,而且必须要以return返回结果,可以查看对象的当前状态。

1
2
3
4
5
6
7
8
9
class Animal:
def __init__(self, name):
self.name = name

def __str__(self):
return "%s"%self.name

cat = Animal("kitty")
print(cat)

3.__del__

在对象被”执行死刑”之前,例如对象不再被调用,即程序会进行自动的垃圾回收,最后自动调用该方法后,回收对象。

1
2
3
4
5
6
7
8
class Num:
def __del__(self):
print("光荣牺牲")

Num = Num()
# 判处死刑
del Num
# 此时Num类已经无实例对象,则会自动调用__del__方法

img

计算一个对象引用计数的方式:sys.getrefcount(objectName)

注意:该次数会比实际个数大一。

4.__mro__

使用__mro__查看对象方法的调用顺序,注意调用时,使用类调用方法

1
2
3
4
5
6
7
8
9
10
class num:
def fun1(self):
print("aa")

class num1(num):
def fun1(self):
print("bb")
c = num1()
print(num1.__mro__)
# (<class '__main__.num1'>, <class '__main__.num'>, <class 'object'>)

5.__new__

该方法用来创建对象

img

16.__repr__

__repr__这个方法会在当前对象使用repr()函数时调用,可以起到指定对象在交互模式中直接输出的效果的作用。

1
2
3
4
5
6
class Person():
def __repr__(self):
return "hi"
p = Person()
print(repr(p))
# 返回hi
strrepr的区别:str打印出来是print()函数的效果,repr是交互式打印的结果。

私有方法

知识点

对象不能直接调用该方法,可以由于验证后进行操作,如短信发送等

语法: __name(self)

1
2
3
4
class Num:
# 私有方法
def __send_msg(self):
print("bababah")

1.注意点

  • 私有方法不会被子类继承,子类不能调用父类的私有方法,而子类继承的父类公有方法里可以调用父类的私有方法

实例运用

再函数内调用私有方法

1
2
3
4
5
6
7
8
9
class Num:
# 私有方法
def __send_msg(self):
print("---send message---")

# 共有方法
def send_msg(self, judge):
if judge>100:
self.__send_msg

创建单例

__init__new__

__init__是在类实例创建之后调用,而__new__方法正是创建这个类实例的方法,__new__产生的实例也就是__init__里面的self.

__new__(cls[,...}) :class 参数会原封不动地传给init

图例

img

使用ifflag_var来标识,在创建单例时,这种思想很重要.


异常

框架

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
try:
# 代码可能出现错误地地方

except# 出现的错误异常种类
print("-----")
except :
print("balabalabala")
except (NameError, FileNotFoundError)
print("balabalabala")
except Exception:
print("balbalblb")
else:
print("当没有产生异常时,调用我~")
finally:
print("babbaab")
其中Exception如果前面的异常都没能捕获到,则Exception一定会捕捉到异常

如果想要查看具体是什么异常,可以使用如下方式:

1
2
except Exception as error:
print(error)

finally不管前面的程序是否产生异常,都会被执行

raise引发一个自己定义的异常


模块–自定义

定义模块内变量

可以在模块内定义变量,然后设置只能在模块内访问

方法:在变量开头添加_

1
2
3
_a =1
def test():
pass

测试模块–自行调用已经外部导入

1
2
3
# 可以起到测试的作用
if __name__ == "__main__"
maindef()

__all__

该方法是为了防止用户直接调用import *,将所有方法都导入,于是只选择一些让用户调用的函数或者类加入到__all__列表中。

1
2
3
4
5
6
7
__all__ = ['test1']

# 只能在外部调用test1函数
def test1():
print("test1")
def test2():
print("test2")

模块存放

尽量把功能相关联的模块存放在同一个位置。

假设在TEST文件夹下创建了2两个文件,当想在另一个位置的项目中调用调用该文件夹下的模块,一般来说是调用不了的,为了使可以调用,可以进行如下操作:

1.在该目录下创建一个__init__.py的文件

该操作的作用就是将该文件目录变成一个包。

2.__init__.py中敲入代码

1
2
3
4
__all__ = ["modulesName"] # 在列表中填入在包中所需要被导入的模块名

# 导入需要导入的模块
import modulesName

在执行上述操作之后,即可调用包内模块。

当直接导入包时,会自动执行init.py内的内容。

制作模块

导入包

默认来说,想要导入包,只能在包所在的目录位置下。

全局导入包来发布模块:

1.在包所在的目录下创建一个setup.py

setup.py文件中复制py_modules所需要的代码:

1
2
3
from distutils import setup

setup(name=" ", version="1.0", description=" ", author=" ", py_modules=[" "])
在py_modules中需要添加的是想要添加全局的模块名,例如:TEST.module1 test为包名,module1为需要导入的模块名。

2.构建模块

命令:python setup.py build

3.生成发布压缩包

命令: python setup.py sdist

可以发布至github

4.安装包

命令: python setup.py install

在执行完上述操作后,就可以全局使用包了。

给程序传递参数

1.导入sys

1
2
import sys
sys.argv
sys.argv用来接收传递的参数

示例:

1
2
3
import sys
name = sys.argv[1]
print("my name is %s" % name)

2.获取当前程序重要引入的所以模块

语法:sys.modules

modules是一个字典,字典的key是模块的名字,字典的value是模块对象。

3.格式化打印模块列表

使用pprint模块

pprint提供了一个pprint()方法,可以对打印的数据进行简单的格式化。
1
2
import pprint
pprint.pprint(sys.modules)

列表推导式

1
a = [i for i in range(1,10)]
1
a = [(i,j) for i in range(1,10) for j in range(3)]

集合

集合内不能有相同的元素,可以用来列表去重:

1
2
3
4
5
6
7
a = [1,1,2,3]
f = set(a)
f
>>> {1,2,3}
b = list(f)
b
>>> [1,2,3]
喜欢的可以对我小额打赏哦,鼓励小编推出更多优质内容~

本文标题:python函数-字典、参数传值、变量范围

文章作者:Keithx的博客~

发布时间:2018年10月08日 - 22:10

最后更新:2018年10月22日 - 19:10

原始链接:http://edmath.cn/Python-Python理论-2018-10-08-python语法基础.html

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

0%
;