Python函数和面向对象,小白看了都说好

python除了使用内置函数以外,还可以自定义函数。我们为什么要定义和使用函数呢?

下面我举个例子,比如我想求10的阶乘

# 求10的阶乘
m = 1
for i in range(1, 11):m *= i
print(m)

代码虽然不长,但是如果我还想求20,21,55,100的阶乘呢?按照上面的方式求几个数的阶乘就要写几个循环,这样我们也能得到想要的答案,但代码是不是显得’难看‘。这时候我们就可以定义一个函数,以后求阶乘只需要调用这个函数就行了。

# 求n的阶乘
def fac(n):result = 1for i in range(1, n + 1):result *= ireturn resultfac(8)      # 8的阶乘
fac(25)     # 25的阶乘
fac(63)     # 63的阶乘
fac(100)    # 100的阶乘

是不是感觉很方便呢?接下来给大家介绍一下函数用法

定义函数

定义一个python函数,下面是函数的基本形式:

def 函数名(参数1,参数2,…,参数n):

​ 函数体

​ return 返回值

我们可以看到python用def来定义一个函数,后面有函数名和英文括号(括号里面可以定义一些参数,参数可以根据具体需求设置,也可以没有参数,参数还可以设置默认值)。下面return可以返回一个值,这个值有时任何形式的数据,当然也可以没有返回值。

接下来是一些实例:

实例1:

def hello_world():return 'hello, world'print(hello_world())  # hello, world

实例2:

def hello(name):print(f'你好,{name}')hello('百里守约')  # 你好,百里守约

实例3:

# 多个数累加
def add(nums):sum = 0for n in nums:sum += nreturn sumnums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(add(nums))    # 55

函数的返回值

return:返回值,如果没有则默认返回None
实例:

def num() :s = 10return sdef num2():s = 10a = num()
b = num2()
print(a, b)   # 10 None

实例:

    s = 'hello, 张三'return sdef hello2():print('hello, jack')a = hello()
print(a)      #hello, 张三
b = hello2()  #hello, jack

函数参数

函数可以设置参数,也可以不设置参数,可以设置一个参数,也可以设置多个参数,同时函数也可以设置默认值。

实例:

import random# 摇色子
def roll_dice(n=2):"""摇色子:param n: 色子个数,默认两个色子:return: 返回色子的总点数"""# points 表示总点数points = 0for _ in range(n):points += random.randrange(1, 7)return pointsprint(roll_dice())   # 默认值为2,摇两个色子,没有默认值调用函数时必须传入参数值
print(roll_dice(3))  # 传入参数3,此时n=3,表示摇3个色子

实例:

def BMI(high, weight, sex):"""体质指数计算:param high:身高 ,单位:米:param weight:体重,单位:千克、公斤:param sex:性别,男:1,女:0:return: 返回体质指数"""bmi = weight / high ** 2if sex == 0:bmi -= 1.1if bmi < 19:print('体重偏轻')elif 19 <= bmi < 25:print('健康体重')elif 25 <= bmi < 30:print('超重')elif 30 <= bmi < 39:print('严重超重')else:print('极度超重')return weight / high ** 2print(BMI(1.6, 50, 1))

此时我们在设置了三个参数,当调用函数时,我们也必须传入三个参数,输入参数 的位置默认和设置参数的位置一致。如果参数有默认值,则调用函数时,带有默认值的参数可以不必输入。

实例

# 加法函数
def sum(a, b):"""加法函数,将a和b相加:param a: 加数:param b: 加数:return: 返回相加之和"""return a+bprint(sum(1, 2))

实例:

# 加法函数
def sum(a, b, c, d, e):"""加法函数,将a, b, c, d, e相加:return: 返回相加之和"""return a+b+c+d+eprint(sum(1, 2, 3, 4, 5))

当输入的参数过多,并且参数的属性一致时,我们可以使用可变参数

可变参数

# 加法函数
def sum(*a):"""加法函数:param a: 表示一个可变参数,存储任意多参数,此时a为一个元组:return: 返回相加之和"""m = 0for i in a:m += ireturn mprint(sum(1, 2, 3))
print(sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))

在参数前面加*号,此时参数为可变参数。可变参数为一个元组,将所有多余的参数全部存在里面。

同时我们可以在不同的项目中调用函数
实例:

module1.py

def hello():print('hello, world')

module2.py

def hello():print('goodbye, world')

test.py

import module1
import module2# 用“模块名.函数名”的方式(完全限定名)调用函数,
module1.hello()    # hello, world
module2.hello()    # goodbye, world

在导入模块时,还可以使用as关键字对模块进行别名,这样我们可以使用更为简短的完全限定名。

import module1 as m1
import module2 as m2m1.hello()    # hello, world
m2.hello()    # goodbye, world

如果我们用from…import…的形式,我们必须使用as关键字对导入函数进行别名,不然两个相同的hello函数,其中一个会被覆盖。

from module1 import hello as h1
from module2 import hello as h2h1()    # hello, world
h2()    # goodbye, world

标准库中的模块和函数

函数 说明
abs 返回一个数的绝对值,例如:abs(-1.3)会返回1.3
bin 把一个整数转换成以'0b'开头的二进制字符串,例如:bin(123)会返回'0b1111011'
chr 将Unicode编码转换成对应的字符,例如:chr(8364)会返回'€'
hex 将一个整数转换成以'0x'开头的十六进制字符串,例如:hex(123)会返回'0x7b'
input 从输入中读取一行,返回读到的字符串。
len 获取字符串、列表等的长度。
max 返回多个参数或一个可迭代对象(后面会讲)中的最大值,例如:max(12, 95, 37)会返回95
min 返回多个参数或一个可迭代对象(后面会讲)中的最小值,例如:min(12, 95, 37)会返回12
oct 把一个整数转换成以'0o'开头的八进制字符串,例如:oct(123)会返回'0o173'
open 打开一个文件并返回文件对象(后面会讲)。
ord 将字符转换成对应的Unicode编码,例如:ord('€')会返回8364
pow 求幂运算,例如:pow(2, 3)会返回8pow(2, 0.5)会返回1.4142135623730951
print 打印输出。
range 构造一个范围序列,例如:range(100)会产生099的整数序列。
round 按照指定的精度对数值进行四舍五入,例如:round(1.23456, 4)会返回1.2346
sum 对一个序列中的项从左到右进行求和运算,例如:sum(range(1, 101))会返回5050
type 返回对象的类型,例如:type(10)会返回int;而type('hello')会返回str

函数进阶

位置参数和关键字参数

def add(a,b,c):

当我想调用函数add时,如add(1,2,3),此时a = 1,b = 2,c = 3,也就是说,传入的参数值与原来函数的参数位置一一对应。此时参数都是位置参数,当然,我们也可以通过参数名=参数值的方式进行传参,如add(a=1,c=3,b=2),因为传入参数时带上了参数名,所以参数位置可以随意改变。

如果我们希望调用函数时必须以参数名=参数值的格式进行传参,我们对函数参数做如下改变:

def add(*,a,b,c):

如此,如果想调用add函数,必须要以参数名=参数值的格式进行传参,否则就会引发异常,这时候的参数我们称之为关键字参数。

参数形式 参数类型 使用实例
def add(a, b, c) a、b、c 都是位置参数 add(1, 2, 3)
def add(*, a, b, c) a、b、c 都是关键字参数 add( a = 1, b = 2, c = 3)
def add(a, *, b, c) a 是位置参数,b、c 是关键字参数 add( 1, b = 2, c = 3)

简单来说,* 前面的参数都是位置参数, * 后面的参数都是关键字参数

前面我们说到可变参数 ( *参数名 )可以容纳任意多的参数个数,我们在设计函数时,如果既不知道调用者会传入的参数个数,也不知道调用者会不会指定参数名,那么同时使用可变参数和关键字参数。关键字参数会将传入的带参数名的参数组装成一个字典,参数名就是字典中键值对的键,而参数值就是字典中键值对的值

def calc(*args, **kwargs):

*args 为可变参数,返回的是一个元组
**kwargs 为可变的关键字参数,返回的是一个字典

实例:

# 加法函数
def sum(*args, **kwargs):result = 0for arg in args:  # args 为元组result += argfor value in kwargs.values():  # kwargs为字典result += valuereturn resultprint(sum(1, 3, 5))  # 9
print(sum(a = 1, b = 4, c = 3))    # 8
print(sum(1, 5, c = 7, d = 3))    # 16

设计函数时,位置参数必须在关键字参数前面;没有默认值的参数必须在有默认值的参数前面。

高级函数

函数本身也可以作为函数的参数或者返回值,这样的函数我们称之为高级函数。

# 加法
def add(num1, num2):return num1 + num2# 减法
def sub(num1, num2):return num1 - num2# 乘法
def mul(num1, num2):return num1 * num2# 除法
def div(num1, num2):return num1 / num2# 高级函数
def sum(*args, start, ft, **kwargs):"""高级函数,自由实现多个数的四则运算start:开始值,加法运算时为0,减法、乘法、除法运算时为0ft:函数名"""result = start_valuefor arg in args:  #result = ft(result, arg)for value in kwargs.values():result = ft(result, value)return resultprint(sum(1, 3, 5, start = 0, ft = add, a = 1, b = 4, c = 3))  # 加法  17
print(sum(1, 3, 5, start = 1, ft = sub, a = 1, b = 4, c = 3))  # 减法  -16
print(sum(1, 3, 5, start = 1, ft = mul, a = 1, b = 4, c = 3))  # 乘法  180
print(sum(1, 3, 5, start = 1, ft = div, a = 1, b = 4, c = 3))  # 除法  0.005555555555555556

此时函数sum已经不局限于一个加法函数,而是可以轻松可以进行四则运算里面任何一个计算方式。需要注意的是,将函数作为参数和调用函数是有显著的区别的,调用函数需要在函数名后面跟上圆括号,而把函数作为参数时只需要函数名即可。我们还可以直接调python标准库中operator模块,它可以提供加法乘法运算,我们直接使用即可。

Lambda函数(匿名函数)

Lambda函数又叫你们函数是一种没有函数名的函数

表达式 ------- lambda 参数1 , …, 参数n : 执行体

执行体通常是一个表达式,其返回值通常就是运算结果

实例:

def sum(*args, start=0, ft=lambda x, y: x + y, **kwargs):result = startfor arg in args:result = ft(result, arg)for value in kwargs.values():result = ft(result, value)return result# 使用默认的lambda函数
print(sum(1, 3, 5, x = 7, y = 9))  # 25
# 重新定义lanbda函数
print(sum(1, 3, 5, x = 7, y = 9, start = 1, ft = lambda x, y: x * y))  # 945

面向对象

首先给大家介绍几个重要的概念。

- 类、对象

类是一个抽象的概念,对象是类的具体实现。

把属于同一个类的共同特征提取出来,我们就得到一个类,比如人是一个类,小明、张三、李四就是一个具体的对象;天体是一个类,那么地球、火星、月球就是一个具体的对象。

  • 封装、继承、多态

    封装:把数据和操作数据的函数从逻辑上组装成一个整体(对象)。隐藏实现细节,暴露简单的调用接口。
    继承:扩展已有的类创建新类,实现对已有类的代码复用。
    多态:给不同的对象发出同样的消息,不同的对象执行了不同的行为。

简单概括一下面向对象编程就是:把一组数据和处理数据的方法组成对象,把行为相同的对象归纳为类,通过封装隐藏对象的内部细节,通过继承实现类的特化和泛化,通过多态实现基于对象类型的动态分派。是一种重要的编程思维和方式。

定义类
加上类名来定义类,通过缩进我们可以确定类的代码块,就如同定义函数那样。在类的代码块中,我们需要写一些函数,我们说过类是一个抽象概念,那么这些函数就是我们对一类对象共同的动态特征的提取。写在类里面的函数我们通常称之为方法,方法就是对象的行为,也就是对象可以接收的消息。方法的第一个参数通常都是self,它代表了接收这个消息的对象本身。

# 定义一个学生类,里面包含学习和玩两个方法
class Student:def study(self, name, course):print(f'{name}正在学习{course}。')def play(self, name, game):print(f'{name}正在玩{game}')

创建和使用对象

# 定义一个学生类,里面包含学习和玩两个方法
class Student:def study(self, course):print(f'学习{course}。')def play(self, name, game):print(f'玩{game}')if __name__ == '__main__':student1 = Student()  # 创建一个对象,命名student1student2 = Student()  # 创建一个对象,命名student2# 调用学生类中的方法student1.study('语文')  # 学习语文。student2.study('数学')  # 学习数学。student1.play('连连看')  # 玩连连看student1.play('推箱子')  # 玩推箱子

初始化方法

我们可以通过给Student类添加__init__方法的方式为学生对象指定属性,同时完成对属性赋初始值的操作,这个方法方法通常也被称为初始化方法。我们对上面的Student类修改,给学生对象添加name(姓名)和age(年龄)两个属性。

# 定义一个学生类,里面包含学习和玩两个方法
class Student:def __init__(self, name, age):self.name = nameself.age = agedef study(self, course):print(f'{self.name}学习{course}。')def play(self, game):print(f'{self.name}玩{game}')if __name__ == '__main__':student1 = Student('张三', 15)  # 创建一个对象,命名student1student2 = Student('李四', 16)  # 创建一个对象,命名student2# 调用学生类中的方法student1.study('语文')  # 张三学习语文。student2.study('数学')  # 李四学习数学。student1.play('连连看')  # 张三玩连连看student1.play('推箱子')  # 张三玩推箱子

在Python中,以两个下划线开头和结尾的方法,我们一般称之为魔术方法或魔法方法。通过__repr__魔术方法,如果我们在打印对象的时候看到的是我们自定义的信息,该方法返回的字符串就是用print函数打印对象的时候会显示的内容。

# 定义一个学生类,里面包含学习和玩两个方法
class Student:def __init__(self, name, age):self.name = nameself.age = agedef study(self, course):print(f'{self.name}学习{course}。')def play(self, game):print(f'{self.name}玩{game}')def __repr__(self):return f'{self.name}: {self.age}'if __name__ == '__main__':student1 = Student('张三', 15)   # 创建一个对象,命名student1print(student1)          # 张三: 15students = [student1, Student('老李四', 16), Student('王五', 25)]print(students)         # [张三: 15, 老李四: 16, 王五: 25]

小程序:

class Clock:"""时间"""def __init__(self, hour=0, minute=0, second=0):self.second = secondself.minute = minuteself.hour = hourdef run(self):self.second += 1if self.second == 60:self.second = 0self.minute += 1if self.minute == 60:self.minute = 0self.hour += 1if self.hour == 24:self.hour = 0def show(self):return f'{self.hour:0>2d}:{self.minute:0>2d}:{self.second:0>2d}'if __name__ == '__main__':clock = Clock(23, 59, 50)while True:os.system('cls')print(clock.show())time.sleep(1)clock.run()

后续还会继续更新,感兴趣的伙伴可以留意

继承和多态
面向对象的编程语言支持在已有类的基础上创建新类,从而减少重复代码的编写,我们称之为继承。提供继承信息的类叫做父类(超类、基类),得到继承信息的类叫做子类(派生类、衍生类),子类可以获得类所有的方法(私有方法除外),同时子类还可定义自己的方法,子类继承父类的方法后,还可以对方法进行重写(重新实现该方法),不同的子类可以对父类的同一个方法给出不同的实现,这样的方法在程序运行时就会表现出多态行为(调用相同的方法,做了不同的事情),我们称之为多态。实例如下:

class Person:"""人"""def __init__(self, name, age, sex):self.name = nameself.age = ageself.sex = sexdef eat(self):print(f'{self.name}在吃饭。')def sleep(self):print(f'{self.name}在睡觉。')class Student(Person):"""学生"""def __init__(self, name, age, sex):# super(Student, self).__init__(name, age, sex)super().__init__(name, age, sex)def study(self, course_name):print(f'{self.name}在学习{course_name}.')class Teacher(Person):"""老师"""def __init__(self, name, age, sex, title):# super(Teacher, self).__init__(name, age)super().__init__(name, age, sex)self.title = titledef eat(self):print(f'{self.name}在吃中药。')def teach(self, course_name):print(f'{self.name}{self.title}正在讲授{course_name}.')stu1 = Student('张三', 15, True)
stu2 = Student('李蕾', 19, False)
tea = Teacher('王二', 99, True, '老中医')
stu1.eat()
stu2.sleep()
tea.teach('望闻问切')
stu1.study('诊脉')

欢迎大家在下方留言评论,一起交流学习~

Python函数和面向对象,小白看了都说好相关推荐

  1. Python(函数与面向对象)

    Python(函数与面向对象) @(Knowledge)[Python, Auspice Vinson] 文章目录 Python(函数与面向对象) @[toc] 函数(function) 定义函数 调 ...

  2. python 函数的参数 (必看)

    python中函数是非常重要的一个知识点,想要把函数学习好,就必须要把函数的参数学习好,这样才能够进行很好的传递参数,发挥出应有的作用 函数的参数分类: 形式参数和实际参数 关键字参数 可变类型参数和 ...

  3. python 函数、面向对象

    一.函数 1.定义个函数,可以对输入的数据进行排序, 通过参数来决定是正向排序还是反向排序. number = input('请输入一串数字:') number_list = list(number) ...

  4. 如何用 Python 哄女朋友开心?看了都说好!

    点击上方 "程序员小乐"关注公众号, 星标或置顶一起成长 每天早上8点20分, 第一时间与你相约 每日英文 Sometimes you play a game even when ...

  5. 小白看完都学会了!mysqlmergeintousing

    前言 阿里巴巴,作为国内互联网公司的Top,算是业界的标杆,有阿里背景的程序员,也更具有权威性.作为程序员,都清楚阿里对于员工要求有多高,技术人员掌握的技术水平更是望尘莫及.所以,大厂程序员的很多经验 ...

  6. 交换机工作原理与配置小白看了都秒懂(配置华为交换机)

    交换机工作原理 讲到交换机必须要了解MAC地址 MAC地址是由48位二进制数组成,通常分为6段,用十六进制表示 交换机的通信方式为单播或者广播,交换机根据MAC转发数据的单位是帧 交换机并不会把收到的 ...

  7. 路由器的原理与作用 及简单静态路由配置小白看了都秒懂(华为路由器)

    路由器(华为) 一.路由器的原理与作用 1.路由表的形成 2.静态路由表 3.动态路由 二.路由器的优点与缺点 1.优点 2.缺点 三.路由器的功能 1.选路功能 2.网络互联 3.数据处理 4.网络 ...

  8. python函数笔记_小白学习笔记之Python函数(一)

    遍历字典 keys() 返回字典的所有的key d={'name':'葫芦娃','age':'7','gender':'男'} for k in d.keys(): print(k) #name,ag ...

  9. 链路捆绑与端口聚合原理与实验结合理解小白看了都秒懂(华为ensp模拟器)不懂不可能的

    链路捆绑与端口聚合 链路捆绑与端口聚合原理与介绍 链路聚合组和链路聚合接口: 成员接口和成员链路: 活动接口和非活动接口.活动链路和非活动链路: 链路接口最大链路活动值: 链路接口最小链路活动值: 链 ...

最新文章

  1. $GLOBALS['HTTP_RAW_POST_DATA'] 和$_POST的区别
  2. 全文搜索引擎 Elasticsearch 简介 及其与 Python 的对接实现
  3. 51CTO专访清无:Nginx_lua的应用及性能对比
  4. 【数据库】-基本特性
  5. Mockito—参数匹配
  6. 错误org.hibernate.InvalidMappingException: Unable to read XML解决方法
  7. OSChina 周二乱弹 ——流川枫与苍井空
  8. ISO/IEC 27017:2015 标准信息安全策略
  9. python 生成器
  10. JQuery监听页面滚动总结
  11. Flutter - 图片/视频选择器(支持拍照及录制视频)
  12. 学习编程是否真的有用?
  13. 饮食男女,人之大欲--nbsp;《饮食…
  14. Zk中组建显示模型mold都有哪些
  15. Virgo与Maven整合开发环境搭建(二)
  16. 场效应管的五大检测方法,你知道几点?
  17. 安装MPlayer播放器(号称Linux中的万能播放器)
  18. 金山云出席网络视听年度盛宴 云+AI让VR从虚拟走向现实
  19. 《大话传输网》学习笔记(一)——————模拟通讯、数字通讯、业务网、GSM移动网、PCM脉冲编码调制(E1)、传送网、PDH和SDH
  20. javascript期末复习题

热门文章

  1. [基本功]分类模型评价标准
  2. 电影周周看——适合新手学习的微信小程序
  3. 新书推荐 |《广告数据定量分析:如何成为一位厉害的广告优化师》
  4. PIP安装本地离线包whl
  5. 网络抖动多少ms算正常_【求助】acrh17 ping结果最高延时多少ms?算正常
  6. PreTranslateMessage(MSG* pMsg)专题
  7. hdwiki v5.1存在SQL注入导致可下载任意文件
  8. 如何评价2021年的B站跨年晚会
  9. 最新百度云不限速软件
  10. 记忆日语的奥秘—日语汉字读音变化