python数据分析--- ch8-9 python函数及类
- 1. Ch8--函数
- 1.1 函数的定义
- 1.2 形参与实参
- 1.2.1 使用位置参数调用函数
- 1.2.2 使用关键字参数调用函数
- 1.3 参数的默认值
- 1.4 可变参数(*)
- 1.4.1 基于元组的可变参数(* 可变参数)
- 1.4.2 基于字典的可变参数(** 可变参数)
- 1.5 函数中变量的作用域
- 1.6 函数类型
- 1.6.1 理解函数类型
- 1.6.2 lambda函数
- 1.6.3练一练
- 2. Ch9--类与对象
- 2.1 面向对象
- 2.1.1 定义类
- 2.1.2 创建对象
- 2.2 类的成员
- 2.2.1 实例变量
- 2.2.2 构造方法
- 2.2.3 实例方法
- 2.2.4 类变量
- 2.2.5 类方法
- 2.3 封装性
- 2.3.1 私有变量
- 2.3.2 私有方法
- 2.3.3 使用属性
- 2.4 继承性
- 2.4.1 多继承性
- 2.4.2 方法重写
- 2.5 多态性
- 2.5.1 继承与多态
- 2.5.2 类型测试与多态
1. Ch8–函数
内容提要
1.1 函数的定义
def rec_s(length,width):
s = length*width
return s
output
长方形面积为60
1.2 形参与实参
s = rec_s(10,6)
print("长方形面积为{}".format(s))
output
长方形面积为60
def circle_s(r,pi):
s = pi*r*r
return s
1.2.1 使用位置参数调用函数
在调用函数时传递的实参与定义函数时的形参顺序一致,这是调用函数的基本形式。
def circle_s(r,pi):
print(f"当前圆的半径为{r}")
print(f"圆周率为{pi}")
s = pi*r*r
return s
r0=7
pi0 = 3.14
s1 = circle_s(r0,pi0)
print("半径为{}的圆,它的面积是{}".format(r,s1))
output
当前圆的半径为7
圆周率为3.14
半径为7.0的圆,它的面积是153.86
r0=7
pi0 = 3.14
s1 = circle_s(pi0,r0)
print("半径为{}的圆,它的面积是{}".format(r,s1))
output
当前圆的半径为3.14
圆周率为7
半径为7.0的圆,它的面积是69.0172
1.2.2 使用关键字参数调用函数
在调用函数时可以采用“关键字=实参”的形式,其中,关键字的名称就是定义函数时形参的名称。
def circle_s(r,pi):
print(f"当前圆的半径为{r}")
print(f"圆周率为{pi}")
s = pi*r*r
return s
r0=7
pi0 = 3.14
s1 = circle_s(r=r0,pi=pi0)#调用函数
print("半径为{}的圆,它的面积是{}".format(r0,s1))
output
当前圆的半径为7
圆周率为3.14
半径为7的圆,它的面积是153.86
r0=7
pi0 = 3.14
s1 = circle_s(pi=pi0,r=r0)#调用函数
print("半径为{}的圆,它的面积是{}".format(r0,s1))
output
当前圆的半径为7
圆周率为3.14
半径为7的圆,它的面积是153.86
1.3 参数的默认值
def circle_s(r,pi=3.14):
print(f"当前圆的半径为{r}")
print(f"圆周率为{pi}")
s = pi*r*r
return s
s3 = circle_s(10)
print(s3)
output
当前圆的半径为10
圆周率为3.14
314.0
s4 = circle_s(10,3.14159)
print(s4)
output
当前圆的半径为10
圆周率为3.14159
314.159
def circle_s(pi=3.14,r):
print(f"当前圆的半径为{r}")
print(f"圆周率为{pi}")
s = pi*r*r
return s
output
File “C:\Users\SHEN HL\AppData\Local\Temp\ipykernel_9548\1344990216.py”, line 1
def circle_s(pi=3.14,r):
^
SyntaxError: non-default argument follows default argument
def circle_s(r,pi=3.14,name="求面积"):
print(f"当前圆的半径为{r},{name}")
print(f"圆周率为{pi}")
s = pi*r*r
return s
print(circle_s(10))
output
当前圆的半径为10,求面积
圆周率为3.14
314.0
1.4 可变参数(*)
1.4.1 基于元组的可变参数(* 可变参数)
def sum1(*numbers):
total =0
for n in numbers:
total+=n
return total
print(sum1(10,20,20,40,50))
output
140
print(sum1(10,20))
output
30
1.4.2 基于字典的可变参数(** 可变参数)
def show_info(**info):
print("-----show info-----")
for k,v in info.items():
print("{}--{}".format(k,v))
show_info(name='Tony',age=18,sex=True)
output
-----show info-----
name–Tony
age–18
sex–True
show_info(fruit='apple',price=15)
output
-----show info-----
fruit–apple
price–15
1.5 函数中变量的作用域
x=20
def print_value():
x=10
print(f"函数中x的取值为{x}")
print_value()
print(x)
output
函数中x的取值为10
20
x1=20
def print_value1():
global x1
x1=10
print(f"函数中x1的取值为{x1}")
print_value1()
print(x1)
output
函数中x1的取值为10
10
print(type(print_value1))
output
<class ‘function’>
1.6 函数类型
Python中的任意一个函数都有数据类型,这种数据类型是被称为函数类型。function
1.6.1 理解函数类型
- 1.一个函数可以作为另一个函数返回值使用
def add_calc(a,b):
print("正在执行加法运算")
return a+b
def sub_calc(a,b):
print("正在执行减法运算")
return a-b
def calc(opt):# opt="+"表示进行加法运算,opt="-"表示进行减法运算,
if opt=="+":
return add_calc
else:
return sub_calc
opt = "+"
f1 = calc(opt)
print(type(f1))
a = 10
b = 5
print("{}{}{}={}".format(a,opt,b,f1(a,b)))
output
<class ‘function’>
正在执行加法运算
10+5=15
opt = "-"
f1 = calc(opt)
# print(type(f1))
a = 10
b = 5
print("{}{}{}={}".format(a,opt,b,f1(a,b)))
output
正在执行减法运算
10-5=5
- 2.一个函数可以作为另一个函数参数使用。
过滤函数 filter()
def f1(x):
return x>5
list1 = [1,4,7,8]
res = filter(f1,list1)
print(list(res))
output
[7, 8]
映射函数 map()
def f2(x):
return x*2
res_map=map(f2,list1)
print(list(res_map))
output
[2, 8, 14, 16]
1.6.2 lambda函数
def calc2(opt):# opt="+"表示进行加法运算,opt="-"表示进行减法运算,
if opt=="+":
return lambda a,b:(a+b)
else:
return lambda a,b:(a-b)
f3=calc2("+")
print(type(f3))
print(f3(5,10))
output
<class ‘function’>
15
f4=calc2("-")
print(type(f4))
print(f4(5,10))
output
<class ‘function’>
-5
1.6.3练一练
def accer(v1,v2,t1,t2):
a=(v2-v1)/(t2-t1)
return a
a = accer(0,10,0,20)
print(f"加速度为{a}")
output
加速度为0.5
a1 = lambda v1,v2,t1,t2:(v2-v1)/(t2-t1)
print(f"加速度为{a1(0,10,0,20)}")
output
加速度为0.5
2. Ch9–类与对象
内容提要
2.1 面向对象
面向对象是一种编程思想,即按照真实世界的思维方式构建软件系统。
2.1.1 定义类
2.1.2 创建对象
class Car(object):
#类体
pass
Car()
output
<main.Car at 0x14ccc191250>
2.2 类的成员
2.2.1 实例变量
实例变量就是对象个体特有的“数据”,例如狗狗的名称和年龄等。
class Dog:
def __init__(self,name,age):#前后是两个下划线
self.name = name
self.age = age
d = Dog('球球',2)
print("狗狗名叫{},{}岁啦".format(d.name,d.age))
output
狗狗名叫球球,2岁啦
2.2.2 构造方法
类中的init()方法是一个非常特殊的方法,用来创建和初始化实例变量,这种方法就是“构造方法”。
class Dog:
def __init__(self,name,age,sex='雌性'):#前后是两个下划线
self.name = name
self.age = age
self.sex = sex
d1 = Dog('球球',2)
d2 = Dog('哈哈',1,'雄性')
d3 = Dog(age=3,sex='雄性',name='拖布')
print('{0}:{1}岁{2}。'.format(d1.name,d1.age,d1.sex))
print('{}:{}岁{}。'.format(d2.name,d2.age,d2.sex))
print('{}:{}岁{}。'.format(d3.name,d3.age,d3.sex))
output
球球:2岁雌性。
哈哈:1岁雄性。
拖布:3岁雄性。
2.2.3 实例方法
实例方法与实例变量一样,都是某个实例(或对象)个体特有的方法。
class Dog:
def __init__(self,name,age,sex='雌性'):#前后是两个下划线
self.name = name
self.age = age
self.sex = sex
# 实例方法
def run(self):
print('{}在跑,running running ......'.format(self.name))
def speak(self,sound):
print('{}在叫,“{}”!'.format(self.name,sound))
dog = Dog("球球",2)
dog.run()
dog.speak('旺 旺 旺')
output
球球在跑,running running …
球球在叫,“旺 旺 旺”!
2.2.4 类变量
类变量是属于类的变量,不属于单个对象。
class Account:
interest_rate=0.0568 # 类变量利率
def __init__(self,owner,amount):
self.owner = owner
self.amount = amount
account = Account('Tony',80000.0)
print('账户名:{}'.format(account.owner))
print('金额:{}'.format(account.amount))
print('利率:{}'.format(Account.interest_rate))
output
账户名:Tony
金额:80000.0
利率:0.0568
2.2.5 类方法
类方法与类变量类似,属于类,不属于个体实例。
class Account:
interest_rate=0.0568 # 类变量利率
def __init__(self,owner,amount):
self.owner = owner
self.amount = amount
@classmethod
def interest_by(cls,amt):
return cls.interest_rate*amt
interest = Account.interest_by(120000.0)
print("计算利息:{0:.4f}".format(interest))
output
计算利息:6816.0000
class Dog:
#类变量是属于类的变量,不属于单个对象。
weight = 7.5#类变量
animal = 'dog'
#构造方法:类中的init()方法是一个非常特殊的方法,用来创建和初始化实例变量,
def __init__(self,name,age):#实例方法,初始化实例变量
self.name = name
self.age = age
#实例方法与实例变量一样,都是某个实例(或对象)个体特有的方法。
def sum1(self):#类方法,不含类变量
return self.age*5
def speak(self,sound):#类方法,包含实例变量和类变量
return "{}在叫,{}".format(self.name,sound)
#类方法与类变量类似,属于类,不属于个体实例。
@classmethod #装饰器 类方法,不含实例变量
def get_health(cls,weight):#cls表示当前类的类型
if cls.weight>10.0:
return "fat"
else:
return "health"
@classmethod
def get_owner(cls,owner):
return f"{cls.animal}的主人是{owner}"
dog = Dog('球球',2)
print("调用类方法1:",dog.sum1())
print("调用类方法2:",dog.speak("汪~汪~汪~"))
print("查看类变量:",Dog.weight)
print("调用类方法3:",Dog.get_health(Dog.weight))
print("调用类方法4:",Dog.get_owner("壮壮"))
output
调用类方法1: 10
调用类方法2: 球球在叫,汪汪汪~
查看类变量: 7.5
调用类方法3: health
调用类方法4: dog的主人是壮壮
2.3 封装性
封装隐藏了对象的内部细节,只保留有限的对外接口,外部调用者不用关心对象的内部细节,使得操作对象变得简单。
2.3.1 私有变量
为了防止外部调用者随意存取类的内部数据(成员变量)内部数据(成员变量)会被封装为“私有变量”。私有变量,则在变量前加上双下画线()。
class Account:
__interest_rate=0.0568 # 类私有变量:利率,变量前加两个下划线
def __init__(self,owner,amount):
self.owner = owner # 实例变量
self.__amount = amount # 私有实例变量
def desc(self):
return "{0}的存款金额为:{1},利率为:{2}。".format(self.owner,
self.__amount,
Account.__interest_rate)
account = Account('Tom',2000000)
account.desc()
output
‘Tom存款金额为:2000000,利率为:0.0568。’
print(account.owner)
# print(account.amount) # 私有变量无法调用
# print(account.__amount) # 私有变量无法调用
# print(account.__interest_rate) # 私有变量无法调用
output
Tom
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
~\AppData\Local\Temp\ipykernel_20524\3225480601.py in <module>
2 # print(account.amount)
3 # print(account.__amount)
----> 4 print(account.__interest_rate)
AttributeError: 'Account' object has no attribute '__interest_rate'
2.3.2 私有方法
私有方法与私有变量的封装是类似的,在方法前加上双下画线()就是私有方法了。
class Account:
__interest_rate=0.0568 # 类私有变量:利率
def __init__(self,owner,amount):
self.owner = owner
self.__amount = amount
def __get_info(self): # 私有方法
return "{0}的存款金额为:{1},利率为:{2}。".format(self.owner,
self.__amount,
Account.__interest_rate)
def desc(self):
print(self.__get_info())
account = Account('Tom',2000000)
account.__get_info()
output
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
~\AppData\Local\Temp\ipykernel_20524\1516856393.py in <module>
1 account = Account('Tom',2000000)
----> 2 account.__get_info()
AttributeError: 'Account' object has no attribute '__get_info'
account.desc()
output
Tom的存款金额为:2000000,利率为:0.0568。
2.3.3 使用属性
为了实现对象的封装,在一个类中不应该有公有的成员变量,这些成员变量应该被设计为私有的,然后通过公有的set(赋值)和get(取值)方法访问。
class Dog:
def __init__(self,name,age):#前后是两个下划线
self.name = name
self.__age = age
# 实例方法
def run(self):
print('{}在跑,running running ......'.format(self.name))
@property #只读的属性变量
def age(self):
return self.__age
@age.setter #此时age可以修改,age为属性的名字
def age(self,age):
self.__age = age
dog = Dog('球球',2)
print("{}年龄:{}岁".format(dog.name,dog.age))
dog.age = 3 #年龄未修改
print("{}修改后年龄:{}岁".format(dog.name,dog.age))
output
球球年龄:2岁
球球修改后年龄:3岁
class Dog:
def __init__(self,name,age):#前后是两个下划线
self.name = name
self.__age = age
# 实例方法
def run(self):
print('{}在跑,running running ......'.format(self.name))
def get_age(self):
return self.__age
def set_age(self,age):
self.__age = age
dog = Dog('球球',2)
print("{}年龄:{}岁".format(dog.name,dog.get_age()))
dog.set_age(3)
print("{}修改后年龄:{}岁".format(dog.name,dog.get_age()))
output
球球年龄:2岁
球球修改后年龄:3岁
2.4 继承性
- 1.继承性也是面向对象重要的基本特性之一。在现实世界中继承关系无处不在。
- 2.例如猫与动物之间的关系:猫是一种特殊动物,具有动物的全部特征和行为,即数据和操作。在面向对象中动物是一般类,被称为“父类”;猫是特殊类,被称为“子类”。特殊类拥有一般类的全部数据和操作,可称之为子类继承父类。
class Animal:
def __init__(self, name):
self. name = name #name
def show_info(self):
return "动物名字:{0}".format(self.name)
def move(self):
print("动一动..")
class Cat(Animal): #括号继承父类Animal
def __init__(self, name, age):
super().__init__(name)#继承父类的name
self.age = age
cat = Cat('Tom',2)
cat.move()
print(cat.show_info())
output
动一动…
动物名字:Tom
2.4.1 多继承性
可能存在多父类的类方法冲突
class Horse: # 马
def __init__(self, name):
self.name = name #name
def show_info(self):
return"马名字:{0}".format(self.name)
def run(self):
print("马跑...")
class Donkey:# 驴
def __init__(self, name):
self.name = name #name
def show_info(self):
return"驴名字:{0}". format(self.name)
def run(self):
print("驴跑...")
def roll(self):
print("驴打滚...")
class Mule(Horse, Donkey): # 骡子
def __init__(self, name, age):
super().__init__(name)
self.age = age
# python默认的规则是多个父类的情况下,哪个父类在前面,有冲突时先继承哪个父类对应的方法
m = Mule('骡宝莉',1)
m.run() # 继承类Horse方法
m.roll() # 继承父类Donkey方法
print(m.show_info()) # 继承父类Horse方法
output
马跑…
驴打滚…
马名字:骡宝莉
2.4.2 方法重写
class Horse:
def __init__(self, name):
self.name = name #name
def show_info(self):
return"马名字:{0}".format(self.name)
def run(self):
print("马跑..")
class Donkey:
def __init__(self, name):
self.name = name #name
def show_info(self):
return"驴的名字:{0}".format(self.name)
def run(self):
print("驴跑..")
def roll(self):
print("驴打滚..")
class Mule(Horse, Donkey):
def __init__(self, name, age):
super().__init__(name)
self.age = age #age
def show_info(self): # 重写父类方法 方法的覆盖或重写
return "骡: {0},{1}岁。".format(self.name, self.age)
m= Mule('骡宝莉', 1)
m.run()#继承父类的Horse()方法
m.roll()#继承父类的Donkey()方法
print(m.show_info())#子类Mule自己方法
output
马跑…
驴打滚…
骡: 骡宝莉, 1岁。
2.5 多态性
- 1.“多态”指对象可以表现出多种形态。
- 2.例如,猫、狗、鸭子都属于动物,它们有“叫”和“动”等行为,但是“叫的方式不同,“动”的方式也不同。
”一龙生九子,九子各不同“
2.5.1 继承与多态
在多个子类继承父类,并重写父类方法后,这些子类所创建的对象之间就是多态的。
这些对象采用不同的方式实现父类方法。
class Animal:
def speak(self):
print('动物叫,但不知道是哪种动物叫!')
class Dog(Animal):
def speak(self):
print('小狗:旺旺旺...')
class Cat(Animal):
def speak(self):
print('小猫:喵喵喵...')
an1 = Dog()
an2 = Cat()
an1.speak()
an2.speak()
output
小狗:旺旺旺…
小猫:喵喵喵…
2.5.2 类型测试与多态
- 1.鸭子类型测试指:若看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟可以被称为鸭子。
- 2.Python支持鸭子类型测试,Python解释器不检查发生多态的对象是否继承了同一个父类,只要它们有相同的行为(方法),它们之间就是多态的。
# 设计一个函数start(),它接收具有“叫"speak()方法的对象:
def start(obj):
obj.speak()
# 定义几个类,都有speak()方法:
class Animal:
def speak(self):
print('动物叫,但不知道是哪种动物叫!')
class Dog(Animal):
def speak(self):
print('小狗:旺旺叫...')
class Cat(Animal):
def speak(self):
print('小猫:喵喵叫..')
class Car:
def speak(self):
print('小汽车:嘀嘀叫...')
# start()可以接收所有speak()方法对象,代码如下:
start(Dog())
start(Cat())
start(Car())
output
小狗:旺旺叫…
小猫:喵喵叫…
小汽车:嘀嘀叫…