面向对象
异常处理
语法错误: 缩进错误, 变量写错, 大小写错误, 缺少符号, 中英文错误… 直接导致程序爆红, 直接终止程序
逻辑错误: 写的代码得到的结果与预期不一致, 代码能运行
NameError: 访问一个没有声明的变量
print(age)
IndexError: 超出索引范围
list1 = [1, 2, 3]
print(list1[5])
TypeError: 类型错误
print(len(123))
KeyError: 获取一个字典不存在的键发生错误
d = {“name”: “张三”}
print(d[“age”])
FileNotFoundError: 文件找不到, 或不存在
f = open(“a.txt”, “r”)
print(f.read())
AttributeError: 当一个对象所有调用属性, 或方法不存在
print(“abc”.time())
-----------------抓取错误-----------------------
1. try … except…语句
try: # try下边的代码块跟预计有错误的代码块
print(name)
except NameError: # 预期的错误, 提前抓取到
# 当遇到这个错误, 下边处理的手段
print("这个变量没有定义!")
name = "张三"
print("程序继续执行...")
print(name)
""""""
2. try … except … else…结构
ls = [1, 2, 3]
try:
print(ls[1])
except IndexError:
# 报错处理代码块
print("已经超出列表的索引范围!")
else:
# 不报错处理代码块
print("try上边的代码不报错, 则执行else下边代码块")
""""""
3. try … except … finally… 结构
string = "12345"
try:
string.date
except Exception as e: # Exception: 就是指的上边报那个错误, 泛指
print("抓取到错误: ", e)
finally:
# 无论是否报错, 都执行下边代码块
print("一定执行的代码块!")
""""""
2.自定义异常
自定义异常, 当你写代码时, 需要一个报错
1. 使用raise, 自定义错误
# ZeroDivisionError: 除数不能为零
def chufa():
a = int(input("除数: "))
b = int(input("被除数: "))
if a == 0:
# raise ValueError("除数不能为0!")
raise ZeroDivisionError("输入除数是0, 错误")
return b / a
print(chufa())
""""""
2. 断言, assert语句, 定义异常
def cf():
a = int(input("除数: "))
b = int(input("被除数: "))
assert a!=0, "除数不能为0!"
return b / a
if __name__ == '__main__':
try:
res = cf()
except AssertionError as a:
print("断言错误: ", a)
else:
print(res)
""""""
json模块
import json
import requests
"""
json模块: 让python数据与json互相转换, json数据是js语言中的, 项目前后端进行数据交互, 使用json数据
requests模块: 获取网页数据, 请求网页, 拿到一个响应, 网页对应的数据
接口(API): 获取里面数据, 一般都是json数据
"""
# http://t.weather.sojson.com/api/weather/city/101180101
weather = "http://t.weather.sojson.com/api/weather/city/101180101"
res = requests.get(url=weather)
f = open("郑州天气.json", "w", encoding="utf-8")
f.write(res.text)
""""""
解析json数据
1. 反序列化, loads(json字符串)将json数据转换为python数据
import json
f = open("郑州天气.json", "r", encoding="utf-8")
json_data = f.read() # json字符串
print(type(json_data))
python_data = json.loads(json_data) # json转python, 字典形式
print(type(python_data))
# print(python_data)
# 取出城市的信息
city_info = python_data["cityInfo"]
print(city_info)
city_name = city_info["city"]
sheng = city_info["parent"]
print(sheng, city_name)
# 取data数据, 主要数据
data = python_data["data"]
forecast = data["forecast"]
for f in forecast:
print(f)
""""""
2. 序列化, dumps(python数据)将python数据转化json数据
import datetime
news = {
"message": "感谢CCTV, 让我们报道这次事件",
"status": 200,
"time": datetime.datetime.today().strftime("%Y-%m-%d %H:%M:%S"),
"data": [
{"new1": "神州13发射成功!"},
{"new2": "台湾回归祖国, 完成国家统一, 见证这个历史时刻吧!"}
]
}
# ensure_ascii: 默认为True, 指定使用ASCII编码, False不使用
# indent=4: 格式化结果
import json
f = open("郑州天气.json", "r", encoding="utf-8")
json_data = f.read()
j = json.dumps(news, ensure_ascii=False, indent=4)
with open("智能2班媒体.json", "w", encoding="utf-8") as js:
js.write(j)
""""""
类介绍
"""
编程思想
面向过程: 分析问题解决所需要的步骤, 然后使用函数将这些步骤一步步的实现
优点: 占用计算机资源少, 代码执行效率高
缺点: 代码量大, 不易维护, 不易扩展, 代码复用性差
面向对象: 将专门事情交给专业的人去做
优点: 代码量少, 易于维护, 易扩展, 代码复用性高
缺点: 占用一定计算机资源
"""
"""
1. 类: 将具有共同特征和行为的一类事务划分一个类, 特征就是属性, 行为就是方法, 相当于一个模板, 或者一张图纸
2. 对象: 通过类实例化出来的, 通过模板创建一个对象, 根据图纸创造出具体的事物
"""
"""
抽象: 从众多事物中抽取出具体的共同的特征
"""
"""
面向对象编程的三大特征: 封装, 继承, 多态
1. 封装: 将属性和方法封装到类里面, 进行保护, 不对外泄露
2. 继承: 子类继承父类, 继承父类属性和方法, 子类可以重新定义属性和方法, 覆盖原来继承的, 一个子类可以继承多个父类的属性和方法, 这个叫多继承
3. 多态: 相同的类可以创造出不同行为的对象
"""
print(type(123))
""""""
定义类
# 定义一个类
# 类名: 需要首字母大写, 遵循大驼峰命名原则, 当多个单词命名时首字母都大写
class Person:
pass
# 首字母大写是规范, 不是必要的要求
class dog:
pass
# 创建学生类
class Student:
pass
# 创建班级类
class Class:
pass
# 创建人的对象, 创建对象的过程叫做实例化对象
zhangsan = Person()
# 创建学生
sunmingchen = Student()
# 查看类, 查看对象
print(Student) # <class '__main__.Student'>
print(sunmingchen) # <__main__.Student object at 0x00000178D739C400>
""""""
添加属性
1. 定义类, 在外部添加属性
class Hero:
pass
# 实例化对象
daji = Hero()
# 添加属性, 通过对象添加属性
daji.name = "妲己"
daji.occ = "法师"
daji.hp = 4600
daji.mp = 800
daji.attact = 180
# 利用对象调用属性
print(f"{daji.name}职业是{daji.occ},血量{daji.hp},魔法值{daji.mp},攻击力{daji.attact}")
""""""
2. 定义类, 添加类属性
class BoyFriend:
# 定义类属性
height = 180
weiht = 130
fule = "白色"
job = "程序猿"
salary = 1000000
""""""
3实例化对象, 这个对象会带有类属性
class BoyFriend:
# 定义类属性
height = 180
weiht = 130
fule = "白色"
job = "程序猿"
salary = 1000000
bf1 = BoyFriend()
print(f"你的男朋友是{bf1.job}, 年薪{bf1.salary}")
bf2 = BoyFriend()
print(f"你的男朋友是{bf2.job}, 年薪{bf2.salary}")
bf2 = BoyFriend()
bf3 = BoyFriend()
""""""
4. 通过类给类添加属性, 这个属性会是类属性, 所有实例化的对象都会拥有这个属性
class BoyFriend:
# 定义类属性
height = 180
weiht = 130
fule = "白色"
job = "程序猿"
salary = 1000000
bf1 = BoyFriend()
print(f"你的男朋友是{bf1.job}, 年薪{bf1.salary}")
bf2 = BoyFriend()
print(f"你的男朋友是{bf2.job}, 年薪{bf2.salary}")
bf2 = BoyFriend()
bf3 = BoyFriend()
BoyFriend.say = "I LOVE YOU!"
bf4 = BoyFriend()
print(bf4.say)
print(bf1.say)
# 通过类调用属性
print(BoyFriend.height, BoyFriend.weiht)
""""""
5,通过对象添加属性, 这个属性只属于这个对象, 其他的对象没有, 类也没有
class BoyFriend:
# 定义类属性
height = 180
weiht = 130
fule = "白色"
job = "程序猿"
salary = 1000000
huazi = BoyFriend()
huazi.sing = "会唱歌"
print(huazi.sing)
# print(bf1.sing)
# 类不能调用对象的属性
# print(BoyFriend.sing)
""""""
属性和方法
“”"
class 类名:
类属性1
类属性2
类属性3
…
def 方法名1(self):
…
def 方法名2(self):
…
“”"
# 类名后边括号中表示继承, 默认是继承object, 不写就是默认值
# object 是所有类的类, 是基类, 所有定义的类都会去继承object
class GirlFriend(object):
height = 180
weight = 180
fule = "黑色"
job = "模特"
def dress(self):
# self: 每个类中定义的方法都有self参数, 必须有, 指的是对象本身
print("洗衣服")
def cooking(self):
print("做饭")
def abc(self):
print("养孩子")
if __name__ == '__main__':
# 实例化对象
g1 = GirlFriend()
print(g1.job) # 访问属性
# 调用方法
g1.cooking()
g1.abc()
# 给对象更改属性
g1.weight = 140
print(g1.weight)
# 再实例化一个对象
g2 = GirlFriend()
print(g2.weight)
g2.weight = 150
print(g2.weight)
""""""
init初始化对象
# 定义类
class Hero(object):
# 类属性定义是固定的值, 只能通过实例化后再修改
# 所有的对象实例化得到的属性都一样
print("1. 类属性被执行!") # 定义类被执行, 这里的类属性会被执行
def __init__(self):
"""__init__(), 方法叫做魔法方法, 是定义类自带的, 来自基类
在实例化类的时候, 会首先调用这个方法, 因此我们可以在这里定义属性
"""
print("2. 这个init方法被调用")
# 实例化对象
xiaoqiao = Hero()
class Dog:
def __init__(self, name, age, breed): # 初始化函数, 实例化对象被自动调用, 进行传参数
# self: 只对象本身, self.name 是对象的属性
self.name = name
self.age = age
self.breed = breed
# 实例化属性, 构造一个对象
zaizai = Dog(name="崽崽", age=3, breed="中华田园犬")
print(zaizai.name, zaizai.age, zaizai.breed)
# 再实例化一个
wkeke = Dog(name="可可", age=5, breed="阿拉斯加雪橇犬")
print(wkeke.name, wkeke.age, wkeke.breed)
""""""
共有和私有属性
# 定义类时, 一些属性在类的内容使用, 在外部限制访问, 称为私有属性
"""
类的内部定义属性和方法, 类外调用属性和方法进行数据操作
当属性不能修改, 就需要在创建属性时进行保护, 在外部不能修改属性
__func__: 首位双下划线表示特殊方法, 系统定义的方法例如: __init__()
_name (半保护): 单下划线开头的属性或方法表示保护类型的成员, 只允许类本身与子类进行调用, 对象可以调用修改
__name (私有属性): 双下划线开头属性或方法表示私有类型
"""
class Cat:
# 共有类属性
name = "汤姆"
# _保护属性
_age = 16
# __私有属性
__job = "下水道"
def __work(self):
print("给人传递情报!")
# 实例化一个对象
tang = Cat()
print(tang.name)
tang.name = "杰克"
print(tang.name)
# 访问被保护属性
print(tang._age)
print(Cat._age)
# 修改被保护的属性
tang._age = 18
print(tang._age)
# 对象访问私有属性, 报错
# print(tang.__job)
# 类访问私有属性, 报错
# print(Cat.__job)
# 加入类名访问
ct = Cat()
# 对象._类名__私有属性 这种方式可以访问到私有属性
print("加入类名访问", ct._Cat__job) # 这种方式, 叫强制访问
# 访问私有方法
# ct.__work()
# Cat.__work()
ct._Cat__work()
""""""
私有属性获取与修改
# 定义类
class Seafood(object):
# 封装: 将属性与方法进行保护不对外界暴露
def __init__(self, name, sex, work, job):
self.name = name # 共有属性
self.sex = sex
self._work = work # 保护属性
self.__job = job # 私有属性, 类外访问不到, 类内可以调用
def get_hidden(self):
"""获取私有属性方法"""
return self.__job
def set_hidden(self, job):
"""修改私有属性方法"""
self.__job = job
if __name__ == '__main__':
baobao = Seafood(name="海绵宝宝", sex="男", work="厨师", job="抓水母")
print(f"{baobao.name}是{baobao.sex}孩子, 职业{baobao._work}")
# 通过调用获取私有属性的方法来查看私有属性
j = baobao.get_hidden()
print(f"{baobao.name}是{baobao.sex}孩子, 职业{baobao._work}, 爱好{j}")
# 再实例化一个章鱼哥
zyg = Seafood(name="章鱼哥", sex="男", work="收银员", job="吹笛子")
print(f"{zyg.name}是{zyg.sex}孩子, 职业{zyg._work}, 爱好{zyg.get_hidden()}")
# 修改这个私有属性, 通过修改私有属性方法进行修改
zyg.set_hidden(job="弹钢琴")
print(f"{zyg.name}是{zyg.sex}孩子, 职业{zyg._work}, 爱好{zyg.get_hidden()}")
""""""
析构函数
import time
# __del__方法: 叫做析构函数, 类魔法方法, python具有垃圾对象回收机制, 当某个示例对象所有引用被清除之后, 所占内存空间自动释放, python提供的__del__()会处理
name = "司马迁"
print(name)
del name
# print(name)
# 定义类
class King(object):
def __init__(self, name):
self.name = name
print("对象实例化, init函数被调用")
def __del__(self):
# 当程序结束, 实例化对象会被回收, 会调用这个函数
print("实例对象%s被删除会调用这个del函数" % self.name)
if __name__ == '__main__':
# 实例化对象
qsh = King(name="嬴政")
# 手动删除对象
del qsh # 执行del语句, 对象会调用 __del__函数删除这个对象
time.sleep(3)
print("结束程序")
""""""
类封装
# 封装: 将的属性,方法进行封装, 隐藏不对外界暴露, 使用私有属性和私有方法
class Class(object):
# object: 基类, 所有类继承基类, 里面定义很多魔法方法, 例如: __init__() 实例方法,(使类属性动态可更改) __del__() 析构函数
cls_name = "类属性"
def __init__(self, cls_room):
# 实例属性, 对象属性
self.cls_room = cls_room
self._job = "造火箭"
self.__hobby = "课下不复习"
def get_hidden(self):
return self.__hobby
def __set_hidden(self, h):
# 方法前边添加双下划线, 称为私有方法
self.__hobby = h
def hidden(self, h):
self.__set_hidden(h)
# 实例对象, 构造一个对象
ai2 = Class(cls_room=206)
print(ai2.cls_name, Class.cls_name) # 类属性, 类和对象都可以访问
# print(ai2.cls_room, Class.cls_room) # 实例属性, 类不能访问, 只有这个实例对象可以访问
# 访问保护属性, 私有属性
# print(ai2._job, Class._job) # 保护属性如果和公有属性对象可以访问, 类不能访问实例属性
# print(ai2.__hobby, Class.__hobby) # 私有属性, 只能类内访问
# 可以通过类内定义的实例方法访问
print(ai2.get_hidden())
# ai2.__set_hidden(h="学而时习之")
# print(ai2.get_hidden())
# 强制访问, 不建议这样做
print(ai2._Class__hobby)
# 强制调用私有方法
ai2._Class__set_hidden(h="时常复习")
print(ai2._Class__hobby)
# 内部的方法可以调用私有方法
ai2.hidden(h="死活不学")
print(ai2.get_hidden())
""""""
封装案例
# 账号密码登陆验证
class Login(object):
# 类属性
__user = "root"
__passwd = "123456"
_userflag = False # 表示验证user不通过
def __init__(self, name):
# 实例属性, 实例化方法
self.name = name
print(f"欢迎{self.name}登陆账号")
def yzuser(self, username):
if username == self.__user:
print("账号验证通过")
self._userflag = True
else:
print("账号验证不通过")
def yzpasswd(self, password):
if self._userflag:
if password == self.__passwd:
print("登陆成功...")
else:
print("登陆失败")
else:
print("请输入正确的账号, 先")
def start(self):
# 验证账号
un = input("账号: ")
login0426.yzuser(username=un)
# 验证密码
pd = input("密码: ")
login0426.yzpasswd(password=pd)
if __name__ == '__main__':
# 测试一下
login0426 = Login(name="zgs")
login0426.start()
""""""
类继承
# 继承: 子类继承父类的属性和方法, 子类实例对象可以调用父类的属性和方法, 也可以继承后重写父类的属性和方法
# 单继承: 子类继承一个父类
class Father(object):
# object: 所有的类继承于基类, 给定义的类提供魔法方法
# 类属性
work = "伐木"
_job = "抓熊"
def day_work(self):
print("砍树, 伐木...")
def _day_job(self):
print("抓熊大, 熊二")
class Son(Father): # 继承一个父类, 单继承
# 子类继承父类
hobby = "徒步"
def study(self):
print("学习开挖掘机...")
# 实例化对象
mao = Son()
print(mao.work, mao._job) # 子类继承了父类的属性, 可以实例对象进行访问
mao.day_work() # 子类继承了父类的方法, 可以用实例对象进行调用
mao._day_job()
print(mao.hobby) # 拥有自己的属性
mao.study() # 自己方法
class GrandFather(object): # 间接父类
work = "土夫子"
def ee(self):
print("会打盗洞")
class Father(GrandFather): # 直接父类
job = "鉴别古董"
def collect(self):
print("收藏古董")
class Son(Father):
hobby = "考古"
def protect(self):
print("保护文物...")
# 实例化
wuxie = Son()
print(wuxie.work, wuxie.job, wuxie.hobby)
wuxie.ee() # 子类继承父类的父类方法, 可以调用
wuxie.collect()
wuxie.protect()
""""""
类多继承
class Father(object):
work = "砌墙"
__attr = "私有属性" # 私有属性只有类内部可以使用, 不能被继承
def day_work(self):
print("去盖房子!")
class Uncle(object):
job = "刷墙"
def day_job(self):
print("刮大白...")
class Son(Father, Uncle): # 继承多个父类, 叫做多继承
hobby = "房屋设计"
def mywork(self):
print("画图纸!")
# 实例化
yangshilei = Son()
yangshilei.day_work()
yangshilei.day_job()
yangshilei.mywork()
# 无法继承父类私有属性
# print(yangshilei.__attr)
""""""
案例-计算面积和周长
class Square(object):
"""计算正方的周长和面积"""
def __init__(self, length):
self.length = length
def perimeter(self):
"""计算周长的方法"""
p = self.length * 4
return p
def area(self):
"""计算面积的方法"""
a = self.length ** 2
return a
# 实例化对象, 一个正方形
s = Square(length=18)
print(s.perimeter()) # 调用计算周长的方法
print(s.area()) # 调用计算面积的方法
# 练习: 升级上边的案例, 定义一个类可以计算出 长方形的周长和面积
class rectangle(object):
"""计算长方形的周长和面积"""
def __init__(self, length, long):
self.length = length
self.long = long
def perimmeter(self):
"""计算周长的方法"""
p = self.length * 2 + self.long * 2
return p
def area(self):
"""计算面积的方法"""
a = self.length * self.long
return a
# 实例化一个对象,一个正方形
s = rectangle(length=10, long=8)
print(s.perimmeter()) # 调用计算周长的方法
print(s.area()) # 计算面积的方法
import math # 数学模块
print(math.pi) # 叫做π
""""""
重写类属性和方法
继承: 子类继承父类的属性和方法, 私有属性不能继承, 子类可以拥有自己的属性和方法, 子类也可以重写父类的属性和方法
继承是为了代码复用
class A(object):
height = 80
width = 60
length = 60
def volume(self):
"""计算体积"""
s = self.length * self.width
return s * self.height
class B(A):
# 新的类需要修改属性, 继承过程中叫重写属性
height = 60 # 子类定义的属性与父类重名, 则子类的属性会覆盖父类的属性, 这是重写
tp = "木头"
def volume(self):
# 子类的方法与父类重名, 子类覆盖父类的方法, 叫做方法重写
return self.height ** 3
# 实例化对象
b = B()
print(b.height, b.width, b.length)
# 调用方法.
res = b.volume()
print(res)
# 练习: 定义父类, 计算三角形, 两个属性, 底边, 高度; 定义方法, 计算三角形的面积; 定义子类继承父类, 子类是正三角形, 只给边长, 重写继承的底边, 高度属性为None, 重写计算面积方法.
import math
class F(object):
bottom_edge = 10
height = 8
def v(self):
return self.bottom_edge * self.height * 0.5
class S(F):
bottom_edge = None
height = None
edge = 6
def v(self):
height = math.sqrt(self.edge ** 2 - (0.5*self.edge) ** 2)
return self.edge * height * 0.5
s = S()
print(f"三角形面积: {s.v():.2f}")
""""""
构造方法重写
import math
class Triangle(object):
def __init__(self, bottom_edge, height):
# 本身就是函数, bottom_edge, height 是形参
self.bedge = bottom_edge # 给实例属性进行赋值
self.height = height # self.属性名 是最终对象的属性, 类不能访问
def v(self):
self.name = "三角形" # 只有在调用v方法时候才会产生name属性
return "%.2f" % (self.bedge * self.height * 0.5)
class ZTriangle(Triangle):
# def __init__(self, bottom_edge, height):
# # 不建议这些重写init构造方法
# self.bedge = bottom_edge
# self.height = height
def __init__(self, bottom_edge, height, bianchnag):
# 继承父类实例属性
# Triangle.__init__(self, bottom_edge, height) # 1.使用父类名调用构造方法
super().__init__(bottom_edge, height) # 2.使用super()调用父类的构造方法, 不需要传入self参数
self.bianchang = bianchnag # 子类在重写父类构造方法时新添加了属性
# self.bedge = None # 子类重写了父类的实例属性
# self.height = None
def v(self):
height = math.sqrt(self.bianchang ** 2 - (0.5*self.bianchang) ** 2)
return f"{self.bianchang * height * 0.5: .2f}"
# 实例化正三角形对象
zt = ZTriangle(bottom_edge=10, height=6, bianchnag=90) # 子类继承了父类的构造方法
# print(zt.name) # 这里实例对象, 这个name属性并没有出现
print(zt.v()) # 调用计算面积函数, 过程中产生了一个name属性
# print(zt.name)
""""""
练习: 定义类, 解决鸡兔同笼问题, 需要判断传入的数据是否准确
class JT(object):
flag = False
def __init__(self, head: int, foot: int):
if head > 0 and foot % 2 == 0:
if head * 2 <= foot <= head*4:
self.head = head
self.foot = foot
self.flag = True
else:
print("输入的脚数量不合理")
else:
print("输入的头数或脚数不合理")
def get_jt(self):
if self.flag:
for t in range(0, self.head+1):
j = self.head - t
if t * 4 + j * 2 == self.foot:
return j, t
else:
print("请输入合理数据")
jt = JT(head=90, foot=80)
print(jt.get_jt())
""""""
不同类型的属性和方法
类属性, 实例属性, 实例方法, 类方法, 静态方法
class Math(object):
# 类属性: 直接在类中定义, 静态属性(不会根据对象进行改变), 类和实例对象可以进行访问
length = 100
width = 80
def __init__(self, name, shape):
# 构造方法, 添加实例属性
self.name = name
self.shape = shape
def func_one(self, num):
# 实例方法, 有参数self, 输入
if num % 2 == 0:
return "偶数"
else:
return "奇数"
@classmethod # @classmethod: 装饰器, 将实例方法转化为类方法
def cls_func(cls):
# cls参数: 类似self参数, cls指的是类本身, self是实例对象本身
# cls只能使用类属性, 不能使用实例属性
print("这个是类方法, 类: ", cls.length)
@staticmethod # 将实例方法变成静态方法, 就是类似普通函数
def fun():
# 静态方法无法使用类属性和实例属性
print("这个就是普通函数, 定义在类中")
if __name__ == '__main__':
# 1. 访问修改类属性
m = Math(name="数学类", shape="四边形")
print(m.length, Math.length) # 对象与类名进行访问类属性
m.length = 10 # 对象修改类属性
Math.width = 8 # 类修改类属性
print(m.length, m.width)
# 2. 访问修改实例属性
a = Math(name="计算类", shape="长方形")
print(a.name, a.shape) # 实例对象可以访问私有属性外其他属性, 都可以访问
a.name = "科学类" # 实例对象可以修改私有属性外其他属性, 都可以修改
print(a.name)
# print(Math.name) # 类不能访问, 修改实例属性, 实例属性在实例化才会产生
# 3. 调用实例方法
t = Math(name="判断奇偶", shape="无")
t.func_one(num=90) # 通过实例对象调用实例方法
Math.func_one(self=t, num=80) # 类名调用实例方法, 必须给self传入参数, 所以需要提前实例化对象当做实参传入
# 4. 调用类方法
Math.cls_func() # 类方法可以使用类直接调用, cls参数就是类自己, 自动传入
h = Math(name="类方法", shape="无")
h.cls_func() # 类实例化的对象可以调用类方法
# 5. 调用静态方法
Math.fun() # 可以使用类调用
mh = Math(name="静态方法", shape="无")
mh.fun() # 可以使用对象调用
多态
多态: 指具有不同功能的函数可以使用相同的函数名, 这样就可以用一个函数名调用不同内容的函数.
class ArmyDog(object):
def bite_enemy(self):
print("追击罪犯")
class DrugDog(object):
def track_drug(self):
print("搜查毒品")
class Police(object):
def army_work(self, dog):
dog.bite_enemy()
def drug_work(self, dog):
dog.track_drug()
# 实例化一个警察
zhu = Police()
zhu.army_work(dog=ArmyDog()) # 实例化的对象调用方法, 需要将实例化dog对象传入
zhu.drug_work(dog=DrugDog()) # 实现追查毒品
# 利用类的多态进行简写
class ArmyDog(object):
def work(self):
# 不同功能的函数可以使用相同的函数名
print("追击罪犯")
class DrugDog(object):
def work(self):
# 不同功能的函数可以使用相同的函数名
print("搜查毒品")
class Police(object):
def work(self, dog):
# 可以用一个函数名调用不同内容的函数
dog.work()
# 实例化一个警察
sun = Police()
# 多态的调用
sun.work(dog=ArmyDog()) # 这个方法起到追击罪犯的作用
sun.work(dog=DrugDog()) # 这个方法起到搜查毒品的作用
将方法变成属性使用
class Student(object):
def __init__(self, id, name, sex, phone):
self.id = id
self.name = name
self.sex = sex
self.__phone = phone
@property # 将这个方法调用方式变成属性方式获取
def phone(self):
# 类的内部可以调用私有属性
return self.__phone
@phone.setter # 将修改属性方法, 变成属性进行修改的方式
def phone(self, p):
# 内部修改私有属性
self.__phone = p
if __name__ == '__main__':
sun = Student(id="1246678", name="孙悟空", sex="男", phone="12345678998")
# 通过方法获取修改私有属性
# print(sun.get_hidden())
# sun.set_hidden(p="1234566789")
# print(sun.get_hidden())
# 公有属性获取修改
print(sun.name)
sun.name = "孙小2"
print(sun.name)
# 让方法变成属性调用方式
cai = Student(id="456789", name="紫霞仙子", sex="女", phone="12312312300")
print(cai.phone)
cai.phone = "1111111111"
print(cai.phone)
魔法方法
class Dog(object):
# 所有的魔法方法来自object(基类)
# 方法前后双下划线, 是Python定义的魔法方法
def __init__(self, name):
# 实例化对象调用构造方法
self.name = name
print("构造方法被调用, 创建实例: %s" % self.name)
def __del__(self):
print("在删除对象, 调用析构函数")
def __add__(self, other):
# 实现实例的加法运算, 字符串加法就是拼接字符串, 数字的加法是数学运算, 列表的加法是合并列表...
return 9527
# def __sub__(self, other): 实现加法运算
# def __mul__(self, other): 实现乘法运算
# def __matmul__(self, other): 实现除法运算
def __len__(self):
# len(): 计算实例对象的长度返回值
count = 0
for i in self.name:
count += 1
return count
# def __lt__(self, other): # 小于 <
# def __le__(self, other): # 小于等于 <=
# def __eq__(self, other): # 等于 ==
# def __ne__(self, other): # 不等于 !=
# def __gt__(self, other): # 大于 >
# def __ge__(self, other): # 大于等于 >=
def __bool__(self):
# 在使用布尔值转化实例对象, 返回的布尔值
return True
def __str__(self):
return "是条狗"
if __name__ == '__main__':
# 实例化
d = Dog(name="多多多多多")
m = Dog(name="毛毛")
print(d + m)
print(len(d))
print(len(m))
print(bool(d))
print(str(d))
""""""