"""
面向过程 和 面向对象(oop:object oriented programming) 的基本概念
面向过程:---侧重于怎么做?
1.把完成某一个需求的 所有步骤 从头到尾 逐步实现
2.根据开发要求,将某些功能独立的代码封装成一个又一个函数
3.最后完成的代码,就是顺序的调用不同的函数
特点:
1.注重步骤与过程,不注重职责分工
2.如果需求复杂,代码会变得很复杂
3.开发复杂项目,没有固定的套路,开发难度很大
面向对象:--谁来做?
相比较函数,面向对象是更大的封装,根据职责在一个对象中封装多个方法
1.在完成某一个需求前,首先确定职责--要做的事(方法)
2.根据职责确定不同的对象,在对象内部封装不同的方法(多个)
3.最后完成代码,就是顺序的让不同的对象调用不同的方法
特点:
1.注重对象和职责,不同的对象承担不同的职责
2.更加适合对复杂的需求变化,是专门应对复杂项目的开发,提供的固定套路
3.需要在面向过程的基础上,再学习一些面向对象的语法
面向对象有两个核心的概念
类:是一群具有相同特征或行为的事物的一个统称,类是抽象的,不能直接使用
对象:由类创造出来的具体存在
在开发中,应该先有类再有对象
类和对象的关系
类是模板,对象是根据这个模板创建出来的
类只需要有一个,对象可以有多个(一张图纸可以造出多个飞机)
类:属性(信息)和方法(你能完成的动作)
1.类名
2.属性
3.方法
1.类名 这类事物的名字,满足大驼峰命名法
大驼峰命名法:
1.每一个单词的首字母大写
2.单词与单词之间没有下划线
2.属性 这个类创建出的对象有什么样的特征
3.方法 这个类创建出的对象有什么样的行为
类名的确定
名词提炼法分析整个业务流程,出现的名词,通常就是找到的类
属性和方法的确定
对 对象的特征描述,通常可以定义成属性
对象具有的行为(动词),通常可以定义为方法
提示:需求中没有涉及的属性或方法在设计类时,不需要考虑
"""
"""
练习1:
需求:
小明今年18岁,身高1.75,每天早上要跑步,会去吃东西
小美今年17岁,身高1.65 小美不跑步,小美喜欢吃东西
Person
name
age
height
run()
eat()
练习2:
一只黄颜色的狗狗叫大黄
看见生人旺旺叫
看见家人摇尾巴
Dog
name
color
shout()
shake()
"""
# 小猫爱吃鱼 小猫要喝水
# Cat eat drink
class Cat:
def eat(self):
print('%s爱吃鱼' %self.name)
def drink(self):
print('小猫要喝水')
# 创建猫对象
# tom = Cat()
# tom.name = 'Tom'
# print(tom)
# addr = id(tom)
#print(addr)
# %x:打印格式为十六进制
# print('%x' %(addr))
# # %d:打印格式为十进制
# print('%d' %(addr))
# tom.drink()
# tom.eat()
"""
初始化方法
创建对象时
1.为对象在内存中分配空间--创建对象
2.调用初始化方法位对象的属性设置初始化值--初始化方法(--init--)
"""
class Cat():
# 初始化方法的参数,创建类时,必须给足
def __init__(self, name):
print('初始化方法')
self.name = name
# 使用类创建一个对象时,会调用初始化方法
cat = Cat('lala')
print(cat.__init__)
dog = Cat('dog')
print(dog.name)
"""
__str__
__del__
"""
class Cat:
def __init__(self, name):
self.name = name
print('%s coming' % (self.name))
# 对象名将不返回内存地址,返回改字符串
def __str__(self):
# 必须放回一个字符串
return '我是 %s' % self.name
# 释放内存时自动执行的方法
def __del__(self):
print(('%s leaving' % (self.name)))
#
tom = Cat('tom')
print(tom)
del tom
print('*' * 40)
小练习
""
需求
1.房子有户型,总面积和家具名称列表
新房子没有任何的家具
2.家具有名字和占地面积,其中
床:占地4平米
衣柜:占地2平米
餐具:占地1.5平米
3.将以上三件家具添加到房子中
4.打印房子时,要输出:户型,总面积,剩余面积,家具名称列表
"""
class house:
def __init__(self, houseType, houseArea):
self.houseType = houseType
self.area = houseArea
self.fire_area = houseArea
self.fitment = []
def __str__(self):
return '户型:%s\n总面积:%s平米\n剩余面积:%s平米\n家具:%s' % (self.houseType, self.area, self.fire_area, ','.join(self.fitment))
def add_fitment(self, fitmentname):
if fitmentname.area < self.fire_area:
self.fitment.append(fitmentname.name)
self.fire_area -= fitmentname.area
else:
print('%s的占地%s平米太大了,房子剩余面积%s平米太小了' % (fitmentname.name, fitmentname.area, self.fire_area))
class fitment:
def __init__(self, name, area):
self.name = name
self.area = area
def __str__(self):
return '%s占地%s平米' % (self.name, self.area)
bed = fitment('架子床', 4)
bureau = fitment('折叠衣柜', 2)
cutlery = fitment('餐桌', 1.5)
# print(bed)
# print(bureau)
# print(cutlery)
xiaoming_house = house('两室一厅', 100)
xiaoming_house.add_fitment(bed)
xiaoming_house.add_fitment(cutlery)
print(xiaoming_house)
python中class的继承
"""
继承: 实现代码的重用,相同的代码不需要重复的写
"""
# 定义父类
class Animal:
def eat(self):
print('吃~~~~')
def drink(self):
print('喝')
def run(self):
print('跑')
def sleep(self):
print('睡')
# 子类继承父类
class Cat(Animal):
def call(self):
print('喵~')
# 创建一个猫对象,可以直接调用继承父类的方法属性,还有自己的方法。
fentiao = Cat()
fentiao.eat()
fentiao.drink()
fentiao.run()
fentiao.sleep()
class Animal:
def eat(self):
print('吃~~~~')
def drink(self):
print('喝')
"""
继承具有传递性
"""
class Cat(Animal):
def call(self):
print('喵~')
class Tom(Cat):
def speak(self):
print('我可以说日语')
kt = Tom()
kt.speak()
# 子类可以继承父类的所有属性和方法
kt.call()
# 继承有传递性,包括父类继承的所有属性和方法
kt.eat()
kt.drink()
"""
当父类方法实现不能满足子类的需求时?可以对方法进行重写
1.覆盖父类的方法
2.对父类方法进行扩展
"""
class Animal:
def eat(self):
print('吃~~~~')
def drink(self):
print('喝')
def run(self):
print('跑')
def sleep(self):
print('睡')
class Cat(Animal):
def call(self):
print('喵~')
class Tom(Cat):
def speak(self):
print('我可以说日语')
def call(self):
print('这是我写的方法')
kt = Tom()
# 如果子类中,重写了父类的方法
# 在运行中,只会调用在子类中重写的方法而不会调用父类的方法
kt.call()
"""
子类重写方法,并调用父类的方法
"""
class Tom(Cat):
def speak(self):
print('我可以说日语')
def call(self):
# 1.针对子类特有的需求,编写代码
print('子类的方法')
# 2.调用原本在父类中封装的方法
# Cat.call(self)
super().call()
kt = Tom()
kt.call()
"""
1.子类可以同时继承多个父类
2.如果方法或属性名称相同时,默认继承成首个参数父类的方法或属性
"""
class A:
def test(self):
print('A----test方法')
def demo(self):
print('A-----demo方法')
class B:
def test(self):
print('B----test方法')
def demo(self):
print('B-----demo方法')
# 同时继承B和A,但是默认B的方法生效
class C(B, A):
pass
c = C()
c.test()
c.demo()
"""
新式类和旧式(经典)类:
object是Python为所有对象提供的基类,提供有一些内置的属性和方法,可以使用dir函数查看
新式类:以object为基类的类,推荐使用
经典类:不以object为基类的类,不推荐使用
在python3.X中定义的类时,如果没有指定父类,会默认使用object作为基类--python3.x中定义的类都是新式类
在python2.x中定义类时,如果没有指定父类,则不会以object作为基类
为保证编写的代码能够同时在python2.x和python3.x运行
今后在定义类时,如果没有父类,建议统一继承自object
"""
class cat:
pass
print(dir(cat))
"""
多态(以封装和继承为前提),不同的子类对象调用相同的方法,产生不同的执行结果
人类
work(self)
程序员 设计师
"""
class Dog(object):
def __init__(self, name):
self.name = name
def game(self):
print('%s 蹦蹦跳跳的玩~' % (self.name))
class Gaofei(Dog):
# 父类方法不能满足子类的方法,重写game方法
def game(self):
print('%s 和米老鼠一起玩~' % (self.name))
class Person(object):
def __init__(self, name):
self.name = name
def game_with_dog(self, dog):
print('%s 和 %s 玩~' % (self.name, dog.name))
dog.game()
# 1.创建一个狗对象
wangcai = Gaofei('高飞')
# 2.创建一个人对象
xiaoming = Person('小明')
# 3.让小明和狗玩
xiaoming.game_with_dog(wangcai)
"""
一切皆对象
类是一个特殊的对象---类对象
在程序运行的时候,类对象(创建实例对象的模板)在内存中只有
一份,通过它可以创建出和很多个对象实例
除了封装实例的属性和方法外,类对象还可以拥有自己的属性和方法
1.类属性
2.类方法
通过 类名. 的方式可以直接访问类的属性
类属性:就是给类对象定义的属性
通常用来记录与这个类相关的特征
类属性不会用于记录对象特征
"""
"""
定义一个工具类,每个工具都有自己的名字
需要知道使用这个类,创建了多少个工具对象
"""
class Tool(object):
# 1.使用赋值语句定义类属性,记录所有工具的数量
count = 0
def __init__(self, name):
self.name = name
# 让类属性 +1
Tool.count += 1
# 创建工具对象
tool1 = Tool('斧头')
# tool2 = Tool('榔头')
# tool3 = Tool('起子')
# 输出工具对象的总数
# 类名.属性名 来获取
print(Tool.count)
"""
类方法
类属性就是针对类对象定义的
使用赋值语句在class关键字下可以定义类属性
类属性用于记录于这个类相关的特性
类方法就是针对类对象定义的方法
在类方法内部就可以直接访问类属性或者调用其他类方法
"""
class Toy(object):
# 1.使用赋值语句定义类属性,记录所有工具的数量
count = 0
def __init__(self,name):
self.name = name
# 让类属性 +1
Toy.count += 1
@classmethod
def show_toy_count(cls):
print('玩具对象的数量 %d' %(cls.count))
# 创建玩具对象
toy1 = Toy('乐高')
toy2 = Toy('泰迪熊')
# 调用类方法
Toy.show_toy_count()
"""
静态方法
在开发的时候,如果需要在类中封装一个方法,这个方法
即不需要访问实例属性或者调用实例方法
也不需要访问类属性或者调用类方法
这个时候,我们就可以把这个方法封装成一个静态方法
"""
class Cat(object):
@staticmethod
def call():
print('喵~')
# 通过 类名. 调用静态方法
Cat.call()
# 不需要创建对象,直接就可以使用
"""
私有属性和私有方法
应用场景及定义方式
应用场景
在实际开发中,对象的某些属性或方法可能只希望在对象的内部使用,
而不希望在外部被访问到
私有属性 就是 对象 不希望公开的 属性
私有方法 就是 对象 不希望公开的 方法
定义方法
在定义属性或方法时,在属性名或者方法名前增加两个下划线,
定义的就是私有属性或方法
"""
class Women(object):
def __init__(self, name):
self.name = name
self.__age = 18
def __secrte(self):
print('%s 的年龄是 %d' % (self.name, self.__age))
lily = Women('lily')
print(lily.name)
# 私有属性,外界不能直接访问
print(lily.__age)
# 私有方法,外界不能直接访问
# lily.secrte()
python中的异常处理方式
"""
异常:
程序在运行的时候,如果python解释器遇到一个错误,会停止程序的执行,
并且提示一些错误的信息,这就是异常
我们在程序开发的时候,很难将所有的特殊情况都处理,通过异常捕获可以针对
突发事件做集中处理,从而保证程序的健壮性和稳定性
在程序开发中,如果对某些代码的执行不能确定(程序语法完全正确)
可以增加try来捕获异常
try:
尝试执行的代码
except 错误类型1:
针对错误类型1,对应的代码处理
except 错误类型2:
针对错误类型2,对应的代码处理
"""
try:
# 不能确定正确执行的代码
num = int(input('请输入一个整数:'))
print('lala')
except:
print('请输入一个整数')
print('#' * 50)
"""
1.提示用户输入一个整数
2.使用8除以用户输入的整数并输出
"""
try:
# 提示用户输入一个整数
num = int(input('请输入一个整数:'))
# 使用8除以用户输入的整数并输出
result = 8 / num
print(result)
except ZeroDivisionError:
print('0不能做除数')
except ValueError:
print('输入的不是数字')
except Exception as result:
print('未知错误 %s' % (result))
finally:
# 无论是否有异常,都会执行的代码
print('~~~~~~~~~~~~~~~~~~~~~')