""" 面向过程 和 面向对象(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('~~~~~~~~~~~~~~~~~~~~~')