一、函数

1. 定义:

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

def 函数名(参数1,参数2):            ----(参数可有可无)

           语句体

           return 变量                 ----(return可有可无)

2. 调用:

函数名

变量=函数名(参数1,参数2)      ----(变量,参数可有可无)

① 调用 ②传参 ③ 接收返回值

3. 举例:

①第一种:无参无返回值

# 定义函数calc 
def calc():
a = int(input('请输入第一个数:'))
b = int(input('请输入第二个数:'))
c = a + b
# print('结果为:',c)
print('结果为:%d'%c)
# 调用
calc()

运行结果为:

  请输入第一个数:1
  请输入第二个数:3
  结果为:4

② 第二种:无参有返回值

def calc():
a = int(input('请输入第一个数:'))
b = int(input('请输入第二个数:'))
c = a + b
return c
# 调用
# print(calc())
result = calc()
print(result)

③ 第三种:有参有返回值

def calc(x,y):
c = x + y
return c

a = int(input('请输入第一个数:'))
b = int(input('请输入第二个数:'))

result = calc(a,b)
print(result)

4. 练习:设计一个计算器

① 输入两个数,自动实现加减乘除

x = int(input('请输入第一个数:'))
y = int(input('请输入第二个数:'))
def add():
z = x + y
return z
def sub():
z = x - y
return z
def mul():
z = x * y
return z
def div():
z = x / y
return z

print('两数相加为:',add())
print('两数相减为:',sub())
print('两数相乘为:',mul())
print('两数相除为:',div())
运行结果为:

  请输入第一个数:6
  请输入第二个数:2
  两数相加为: 8
  两数相减为: 4
  两数相乘为: 12
  两数相除为: 3.0

② 进阶:根据用户输入的计算符号计算结果

def calc():
x = int(input('请输入第一个数:'))
y = int(input('请输入第二个数:'))
z = input('请输入运算符号:+ - * /:')
if z == '+':
result = x + y
print('两数相加为:',result)
elif z == '-':
result = x - y
print('两数相减为:',result)
elif z == '*':
result = x * y
print('两数相乘为:',result)
elif z == '/':
try:
result = x / y
print('两数相除为:',result)
except ZeroDivisionError:
print('除数不能为0!')
else:
print('运算符号输入错误,请重新输入!')
calc()

5. 参数的几种类型:

① 位置参数:调用函数时根据函数定义的参数位置来传递参数

def person(name,sex):
sex_dict = {1:'先生',2:'女士'}
print('hello %s %s,welcome~'%(name,sex_dict.get(sex,'女士')))
person('baby',2)
运行结果为:
hello baby 女士,welcome~

注意:位置参数的两个参数的顺序必须一一对应,且少一个参数都不可以

② 默认参数:用于定义函数,为参数提供默认值,调用函数时可传可不传该默认参数的值

注意:定义默认参数时,必选参数在前、默认参数在后(包括函数定义和调用),否则python解释器会报错,且默认参数必须执行不变对象!

 1)默认参数指向可变对象时:(保留了上次执行的结果)

def add_end(L = []):
L.append('end')
return L

print(add_end())
print(add_end())
运行结果:

['end']
['end', 'end']

 2)默认参数指向不变对象时:

def add_end(L = None):
if L is None:
L = []
L.append('end')
return L

print(add_end())
print(add_end())
运行结果:

['end']
['end']

③ 可变参数:定义函数时,有时候我们不确定调用的时候会传递多少个参数(不传参也可以)。此时,可用位置参数,或者关键字参数,来进行参数传递

我们传进的所有参数都会被args变量收集,它会根据传进参数的位置合并为一个元组(tuple),args是元组类型,这就是位置传递

1)

def calc(*args):
print(*args) # *args打印出来是一个一个的整型的数
print(args,type(args)) # args默认保存为元组,打印出来是一个元组
for i in args:
print('传入的值分别为:',i)

# 可变参数传参形式1 - 常用(通过引用的方式必须带*)
m = [1,2,3]
calc(*m)

运行结果:
1 2 3
(1, 2, 3) <class 'tuple'>
传入的值分别为: 1
传入的值分别为: 2
传入的值分别为: 3
2)

def calc(*args):
print(*args) # *args打印出来是一个一个的整型的数
print(args,type(args)) # args默认保存为元组,打印出来是一个元组
for i in args:
print('传入的值分别为:',i)

n = (3,4,5)
calc(*n)

3)
def calc(*args):
print(*args) # *args打印出来是一个一个的整型的数
print(args,type(args)) # args默认保存为元组,打印出来是一个元组
for i in args:
print('传入的值分别为:',i)

# 可变参数传参形式2
calc(1,2,3)

④ 关键字参数:用于函数调用,通过“键-值”形式加以指定。可以让函数更加清晰、容易使用,同时也清除了参数的顺序需求。

有位置参数时,位置参数必须在关键字参数的前面,但关键字参数之间不存在先后顺序

kargs是一个字典(dict),收集所有关键字参数

def person(name,age,**kwargs):
print('name',name,'age',age,kwargs)
print(kwargs,type(kwargs))

person('xiaoming',21,sex = 'male',color = 'blue')
person('xiaoming',21) # 可变参数和关键字参数可以不传
person('xiaoming',21,sex = 1)
person('xiaoming',21,sex = 'male')

总结:

可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。

而关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。

关键字参数有什么用?

它可以扩展函数的功能。比如,在person函数里,我们保证能接收到name和age这两个参数,但是,如果调用者愿意提供更多的参数,我们也能收到。试想你正在做一个用户注册的功能,除了用户名和年龄是必填项外,其他都是可选项,利用关键字参数来定义这个函数就能满足注册的需求。

和可变参数类似,也可以先组装出一个dict,然后,把该dict转换为关键字参数传进去:

def person(name,age,**kwargs):
print('name',name,'age',age,kwargs)

extra = {'city':'beijing','job':'Engineer'}
person('xiaoming',25,**extra)

运行结果为:
name xiaoming age 25 {'job': 'Engineer', 'city': 'beijing'}

6. 异常处理:

① 已知类型:try ... except

def calc(a,b):
try:
print(a/b)
except ZeroDivisionError:
print('除数不能为0!')

a = int(input('-'))
b = int(input('-'))

calc(a,b)

运行结果为:
-2
-0
除数不能为0!

② 未知类型:https://www.cnblogs.com/zln1021/p/6106185.html

def calc(a,b):
try:
print(a/b)
except Exception: # BaseException
print('除数不能为0!')

a = int(input('-'))
b = int(input('-'))

calc(a,b)

③ 多重异常:

def calc(a,b):
try:
print(a/b)
except NameError:
print('该对象未申明')
except ZeroDivisionError:
print('除数不能为0')

a = int(input('-'))
b = int(input('-'))

calc(a,b)

④ 最终处理:

def calc(a,b):
try:
print(a/b)
except NameError:
print('该对象未申明')
except ZeroDivisionError as msg:
# print(msg)
print('除数不能为0',msg)
finally:
print('程序执行完毕')

a = int(input('-'))
b = int(input('-'))
calc(a,b)

⑤ else:在程序没有抛出异常的时候,继续执行else语句

def calc(a,b):
try:
print(a/b)
except NameError:
print('该对象未申明')
except TypeError as msg:
print(msg)
else:
print('程序执行完毕!')

a = int(input('请输入第一个数:'))
b = int(input('请输入第二个数:'))
calc(a,b)

⑥抛出异常:异常必须为exception的子类

raise TypeError('类型错误')

def calc(a,b):
try:
print(a/b)
except NameError:
print('该对象未申明')
# 查看异常后不做处理继续抛出异常
raise
except ZeroDivisionError as msg:
# print(msg)
print('除数不能为0',msg)
else:
print('程序执行完毕')

a = int(input('-'))
b = int(input('-'))
calc(a,b)

⑦ 练习:name没有定义,type异常,并抛出是何种异常

def calc(a,b):
try:
print(a/b)
except NameError as msg:
print('该对象未申明',msg)
raise
except TypeError as msg:
print(msg)
raise
else:
print('程序执行完毕!')

a = int(input('请输入第一个数:'))
b = int(input('请输入第二个数:'))
calc(a,b)

7. 文件IO:

文件操作流程:

① 找到文件 :新建文件new --> file-->data.txt,查看文件路径:右键data,选择Show in Explorer(路径支持绝对路径和相对路径)

data文件内容如下:

a,b,c
tom,lucy,lily
1,2,3

② 打开文件:(文件路径和打开模式)

打开文件的模式有:

  • r:只读模式(默认)。
  • w:只写模式(不可读;不存在则创建;存在则删除内容)
  • a:追加模式 -- append(可读;不存在则创建;存在则只追加内容)

  "+" 表示可以同时读写某个文件

  • r+:可读写文件(可读;可写;可追加)
  • w+:写读
  • a+:同a
f = open('F:\Code\VIPtest2\data.txt','r')

③ 操作文件:读、写

读取文件所有内容:print(f.read())   -- 文件大时不要用

读取指定长度字节的数据:print(f.read(4))   -- 读取前4个字节的内容

读取整行:print(f.readline())   -- 读取光标所在位置的整行

读取前5行:

for i in range(5):
print(f.readline())

如果需要读取5-10行,中间加个if判断即可

读取所有行:print(f.readlines())    -- 列表形式输出

运行结果:['a,b,c\n', 'tom,lucy,lily\n', '1,2,3\n', '\n']

写:

f = open('F:\Code\VIPtest2\data2.txt','r+')
f.write('hello python!\n')
f.write('welcome~')
f.close()

④ 关闭文件:f.close()

 

作业:只取出data中的数字并写入另外的文件

思路:

① 读取文件中的所有数据 -- readlines

② 从列表中找出含有的数字 

    判断列表中的每一个元素是否含有数字 -- 将列表中的每一个元素(数据的行)取出来,作为一个小的列表

    判断每一个小的列表是否含有数字 isdigit(),如果是数字,则追加到一个新的列表

③ 排序、写入

data:

a,b,c
tom,lucy,lily
1,3,9,6,8,4,5

代码:

f = open('F:\Code\VIPtest2\data.txt','r')
lines = f.readlines()
# print(lines)
lists = []
for l in lines:
# print(l)
s = l.split(',') # 切片
# print(s)
for m in s:
if m.strip().isdigit(): # 判断是否为数字
lists.append(m.strip())
else:
continue
for i in range(1,len(lists)): # 冒泡排序
for j in range(0,len(lists)-i):
if lists[j] > lists[j+1]:
lists[j],lists[j+1] = lists[j+1],lists[j]
print(lists)
f1 = open('F:\Code\VIPtest2\data3.txt','r+')
f1.write(str(lists))
f.close()

8. 模块和包:

① 模块:模块是一个包含所有你定义的函数和变量的文件,其后缀名是.py,模块可以被别的程序引入,以使用该模块中的函数等功能,这也是使用python标准库的方法。

Mymodule:
def fun1():
print('我是fun1函数')

def fun2():
print('我是fun2函数')

print('name的值为:',__name__)
# 每个模块都有一个__name__属性,当其值为:'__main__'时,表明该模块自身在运行,否则是被引入
if __name__ == '__main__':
fun1()
fun2()

__name__的作用:一个模块被另一个程序第一次引入时,其主程序将运行。如果我们想在模块被引入时,模块中的某一程序块不执行,我们可以用__name__属性来使该程序块仅在该模块自身运行时执行

② 包:当一个目录内含有__init__.py文件时,就可以视该目录为一个包。

③ 调用包和模块:

第一种调用方式:import 模块名/ 包名(只能导入名称)

右键practice-->mark directory as->resource root(将当前路径加入python查找的默认路径

如果通过import调用,使用包内的方法需要通过包名.函数名的形式

Mymodule.fun1()

第二种调用方式:from 包名 import 模块名

from ... import的形式导入,from后面只能跟包和模块名,不能跟函数名,import后面跟函数或者类名

绝对导入:from practice import module

from Mymodule import fun1

通过from-import的形式可以直接使用函数名

fun1()
fun2()

第三种调用方式:相对导入

from .database import Database   # 点号表示使用当前路径的database模块

from ..database import Database  # 使用两个点号表示访问上层的父类

第四种调用方式:通过import* 可以导入多个函数

from Mymodule import *

二、面向对象的类、属性、方法

1. 基础:

类:具有相同的特性,且能够完成某些动作的事物组成的一个集合

属性:类中的事物所具有的特性,趋于静态

方法:类中的事物所能够完成的动作或功能,趋于动态

实例/对象:类中某一个具体的对象或实例

实例化:定义类中某一个对象的过程

2. 类的定义:

class 类名(object):

            属性

            方法

注意:属性和方法可以为空,里面直接写pass即可,表示是一个空类

举例:

 

3. 类的实例化:

变量=类名('xx')  ---是否需要传参就看__init__方法中除了self是否还有其他参数

4. 类中方法的调用:

实例名.方法名('xx')  ---是否需要传参就看该方法中除了self是否还有其他参数

练习:

① 定义一个学生类:Student、内部含有一个方法:study,实现打印:小明学习xx课程

 

② 定义一个类名:Student—学生、类内部含有一个属性:sno—学号,一个方法:study—学习,实现打印:学号为xx的学生,学习xx课程

 

5. 继承:为了提高代码的复用性,可以通过继承来减少属性和方法的编写

语法:继承谁就在括号中写谁-类名

 

例子:

 

练习:

定义一个Teacher类,继承Person类,拥有自身的属性工号gh,自身的方法:teach教课(课程);

① 实现gh为xx的老师,教xx课

② 实现gh为xx老师,在xx上班,一月工资xx

③ 名字是xx,工号为xx的老师,吃饭

6.重写:当继承的父类方法不满足自身需要的时候,我们可以重写该父类的方法,注意,必须同名

例子:

调用父类的方法:

多重继承的注意事项:

7.多态:多态性是指具有不同功能的函数可以使用相同的函数名,这样就可以用一个函数名调用不同内容的函数。在面向对象方法中一般是这样表述多态性:向不同的对象发送同一条消息,不同的对象在接收时会产生不同的行为(即方法)。也就是说,每个对象可以用自己的方式去响应共同的消息。所谓消息,就是调用函数,不同的行为就是指不同的实现,即执行不同的函数。

8.私有属性和私有方法

类的私有属性

__abc:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问。在类内部的方法中使用时 self.__abc。

类的方法

在类的内部,使用 def 关键字来定义一个方法,与一般函数定义不同,类方法必须包含参数 self,且为第一个参数,self 代表的是类的实例。

self 的名字并不是规定死的,也可以使用 this,但是最好还是按照约定是用 self。

类的私有方法

__method:两个下划线开头,声明该方法为私有方法,只能在类的内部调用 ,不能在类的外部调用。self.__ methods。

 

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄