面向对象方法

面向对象

异常处理

语法错误: 缩进错误, 变量写错, 大小写错误, 缺少符号, 中英文错误… 直接导致程序爆红, 直接终止程序
逻辑错误: 写的代码得到的结果与预期不一致, 代码能运行
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))
    
""""""

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值