[TOC]
1. 函数的定义
python中函数有两种:
- python自带的函数
- 用户定义函数
返回多个值
原来返回值是一个tuple!但是,在语法上,返回一个tuple可以省略括号,而多个变量可以同时接收一个tuple,按位置赋给对应的值,所以,Python的函数返回多值其实就是返回一个tuple,但写起来更方便
1.1函数的参数
参数 | 含义 | 输入 |
---|---|---|
位置参数 | def power(x,n) |
实际参数 |
默认参数 | def power(x,n=2) |
实际+默认参数(需要改变时) |
可变参数 | def power(*args) |
传入任意个参数,内部组装成tuple |
关键字参数 | def person(name, age, **kw) |
传入带参数名的参数,组装成dict |
命名关键字参数 | def person(name,age,*, city, job) |
限制关键字参数的名字(必须传入参数名) |
- 顺序: 必选参数<---默认参数<---可变参数<---命名关键字参数<---关键字参数
# 关键字参数
def person(name, age, **kw):
print('name:', name, 'age:', age, 'other:', kw)
person('hao', 20) # name: Michael age: 30 other: {}
person('hao', 20, gener = 'M', job = 'Engineer') # name: Adam age: 45 other: {'gender': 'M', 'job': 'Engineer'}
extra = {'city': 'Beijing', 'job': 'Engineer'}
person('Jack', 24, **extra)
# 命名关键字参数
def person(name, age, *, city='Beijing', job):
print(name, age, city, job)
person('Jack', 24, job = '123')
person('Jack', 24, city = 'Beijing', job = 'Engineer')
# Combination
# 可变 + 关键字参数
def f1(a, b, c=0, *args, **kw):
print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)
f1(1, 2, 3, 'a', 'b') # a = 1 b = 2 c = 3 args = ('a', 'b') kw = {'x': 99}
f1(1, 2, 3, 'a', 'b', x=99) # a = 1 b = 2 c = 0 d = 99 kw = {'ext': None}
# 默认参数 + 命名关键字参数 + 关键字参数
def f2(a, b, c=0, *, d, **kw):
print('a =', a, 'b =', b, 'c =', c, 'd =', d, 'kw =', kw)
f2(1, 2, d=99, ext=None) # a = 1 b = 2 c = 0 d = 99 kw = {'ext': None}
2. 面向对象编程
- 面向过程: 根据业务逻辑从上到下写代码
- 面向对象: 对数据与函数绑定到一起,进行封装,这样更快速的开发过程,减少代码重复使用
数据封装、继承和多态是面向对象的三大特点
2.1. 类(抽象概念)和对象(具体概念)
玩具模具(类)-》 火车玩具,飞机玩具..(对象)
类的组成结构
- 类名:狗
- 类的属性:一组数据(狗的颜色,性别...)
- 类的方法: 运行进行操作的方法行为(行为,会叫,会咬人...)-> 用函数设计
类的组成 | 特性 | 例子 | 例子 |
---|---|---|---|
类名 | 名称 | 狗 | 人 |
类的属性 | 一组数据 | 狗的颜色,性别 | 身高,年龄 |
类的方法 | 运行进行操作的方法行为 | 行为,会叫,会咬人 | 跑,打架 |
- 类是创建实例的模板,而实例则是一个一个具体的对象,各个实例拥有的数据都互相独立,互不影响;
- 方法就是与实例绑定的函数,和普通函数不同,方法可以直接访问实例的数据;
- 通过在实例上调用方法,我们就直接操作了对象内部的数据,但无需知道方法内部的实现细节。
- 继承可以把父类的所有功能都直接拿过来,这样就不必重零做起,子类只需要新增自己特有的方法,也可以把父类不适合的方法覆盖重写。
(1). 定义类
# 定义类
class Dog(object):
# 定义初始化方法
def __init__(self,weight,color):
"""
self: python会把对象的地址自动传给self,不要自己传
weight, color: 接收外部属性
"""
# 定义属性
self.weight = weight
self.color = color
# 魔法方法: 当只打印Dog对象的时候,就可以打印这里的东西
def __str__(self):
msg = "dog weight" + self.weight + "color" + self.color
return "哈哈哈"
def getweight(self):
return self.weight
def getcolor(self):
return self.color
def setweight(self):
self.weight = 100
def setcolor(self):
self.color = "green"
# 定义方法
def bark(self):
"""
self: python解释器默认把调用该class的对象地址给它
"""
print("666")
def run(self):
print("777")
# 创建对象
huskey = Dog(5, 'Black') # 创建一个哈士奇
keji = Dog(10, 'Green')
huskey.bark() # 哈士奇叫
huskey.run() # 哈士奇跑
huskey.weight = 100 # 哈士奇属性
huskey.color = 'green'
self
表示自己,表示调用类的对象本身- python中类似
__***__
的方法,是魔法方法,有特殊用途
(2). 类的数据封装
面向对象编程的一个重要特点就是数据封装,比如在上面例子中,Dog
类的每个实例都有weight和color,我们可以直接在Dog
类的内部定义访问数据的函数,这样,就把“数据”给封装起来了。这些封装数据的函数是和Dog
类本身是关联起来的,我们称之为类的方法:
class Dog(object):
def __init__(self, weight, color):
self.weight = weight
self.color = color
def print_dog(self):
print('%s: %s' % (self.weight, self.color))
我们从外部看Dog
类,就只需要知道,创建实例需要给出weight
和color
,而如何打印,都是在Dog
类的内部定义的,这些数据和逻辑被“封装”起来了,调用很容易,但却不用知道内部实现的细节。