python笔记-类和实例

1、类的基本概念

  • class:表明这是一个类
  • ClassName:类的名字
  • ():父类集合的开始和结束
  • object:父类的名字,定义类继承自父类,可以不写,默认是object,object是所有类的直接或间接父类
  • 类的实例化(创建对象)
    -实例名 = 类()的方式实例化对象,为类创建一个实例
点击查看代码
class Player(object):  #object是python的基类
    pass

tom = Player()  #类的实例化(创建一个对象)
print(f"tom的类型是:{type(tom)}")
print(f"tom是Player类吗:{isinstance(tom, Player)}")
print(f"tom是object类吗:{isinstance(tom, object)}")

2、实例的属性(类似于变量)

  • 属于特定对象实例的属性,比如人:姓名、性别、年龄、籍贯、所在城市、工作岗位等就是人的属性;
  • def init(self): #初始化函数,self代表实例化的对象
  • 在实例化对象时会默认自动执行类中的初始化函数
  • 每个实例都有自己独立的副本
  • 典型用途:对象个性化数据
点击查看代码
class Player(object):
    def __init__(self,name,age,city):   #初始化函数(构造函数)
        print(f"打印初始化函数!!!")
        self.name = name
        self.age = age
        self.city = city
#类的实例化类(创建对象)
jake = Player('jake',24,'西安')
jake.city = '北京'  #对象属性重新赋值
print(f"对象jake的基本信息:{jake.name},{jake.age},{jake.city}")
tom = Player('tom',38,'重庆')
print(f"对象tom的基本信息:{tom.name},{tom.age},{tom.city}")
tom.height = 180   #对象在初始化函数外增加属性并赋值
tom.city = '成都'
print(f"tom的所有属性:{tom.__dict__}")   #获取实例对象的所有属性

3、类的属性(类似与全局变量)

  • 属于类本身的属性,所有实例对象共享同一属性,称为类属性
  • 在类定义中直接定义,不在任何方法内
  • 典型应用:常量、计数器、共享配置
点击查看代码
class Player(object):
    number = 0    #类属性
    def __init__(self,name,age,city):   #初始化函数
        print(f"初始化函数!!!")
        self.name = name    #实例属性
        self.age = age
        self.city = city
        Player.number += 1
jack = Player('jack',26,'杭州')
print(jack.__dict__)
print(f"欢迎王者荣耀第{Player.number}个用户注册成功!")
tom = Player('tom',28,'绵阳')
print(f"欢迎王者荣耀第{Player.number}个用户注册成功!")

4、实例方法(类似于函数)

  • 定义在类中,第一个参数为 self 的方法,用于操作实例的属性和状态。self 代表类的当前实例。
  • 调用方法:必须通过类的实例来调用 实例名.实例方法名()
  • 访问权限:可以自由访问和修改实例属性
  • 作用:实现对象的行为和操作
  • 设计原则:
    保持方法单一职责
    使用描述性方法名
    考虑使用属性装饰器替代简单getter/setter
    区分公共方法和私有方法(使用 _ 前缀)
点击查看代码
class Player(object):
    number = 0    #类属性
    levels = ['废铁', '青铜', '白银', '黄金', '钻石', '王者']
    def __init__(self,name,age,city,level):   #初始化函数
        self.name = name    #实例属性
        self.age = age
        self.city = city
        if level not in Player.levels:
            raise Exception(f"你的等级不在等级范围中,请重新设置")
        else:
            self.level = level
        Player.number += 1
    # 定义一个实例方法(与定义函数类似)
    def show(self):
        print(f"我是LOL的第{Player.number}个玩家.\n我的名字是{self.name}.我来自{self.city}.\n我的等级是{self.level}")
    #定义一个升级实例方法
    def level_up(self):
        index_1 = Player.levels.index(self.level)
        if index_1 < len(Player.levels)-1:
            self.level = Player.levels[index_1 + 1]
    #获取一个武器的实例方法
    def get_weapon(self,weapon):
        self.weapon = weapon
    #查看武器的实例方法,调用weapon类中的实力方法
    def show_weapon(self):
        return self.weapon.show_weapon()

#武器:名字、攻击值、等级
class weapon(object):
    number = 0
    max_damage = 10000
    levels = ['废铁','青铜','白银','黄金','钻石','王者']
    def __init__(self,name,damage,level):
        self.name = name
        self.damage = damage
        self.level = level
        weapon.number += 1
        if damage > weapon.max_damage:
            raise Exception(f'最大伤害值是10000,请重试!')
        if level not in weapon.levels:
            raise Exception(f"武器等级不在等级范围列表中,请重新设置")

    #打印武器信息的实例方法
    def show_weapon(self):
        for k,v in self.__dict__.items():
            if k =='name':
                print(f"武器的名称是:{v}")
            elif k == 'damage':
                print(f"武器的伤害值是:{v}")
            else:
                print(f"武器的等级是:{v}")
try:
    #实例化武器对象
    gun = weapon('步枪',100000,'废铁')
    print(f"gun的所有属性:{gun.__dict__}")
    print(f"欢迎王者荣耀第{weapon.number}个武器设置成功!")
    arrow = weapon('弓箭',800,'王者')
    print(f"arrow的所有属性:{arrow.__dict__}")
    print(f"欢迎王者荣耀第{weapon.number}个武器设置成功!")
except Exception as e:
    print(e)

jack = Player('jack',28,'重庆','青铜')
jack.show()
jack.level_up()
jack.show()
jack.level_up()
jack.show()
jack.level_up()
jack.show()
jack.level_up()
jack.show()
jack.level_up()
jack.show()
gun = weapon('步枪',2000,'废铁')
jack.get_weapon(gun)
jack.show_weapon()

5、类方法

  • 类方法是绑定到类本身而不是实例的方法,使用 @classmethod 装饰器定义,第一个参数为 cls(代表类本身)。
  • 类方法示例
点击查看代码
class Player(object):
    number = 0    #类属性
    levels = ['废铁', '青铜', '白银', '黄金', '钻石', '王者']
    def __init__(self,name,age,city,level):   #初始化函数
        self.name = name    #实例属性
        self.age = age
        self.city = city
        if level not in Player.levels:
            raise Exception(f"你的等级不在等级范围中,请重新设置")
        else:
            self.level = level
        Player.number += 1
    # 定义一个实例方法(与定义函数类似)
    def show(self):
        print(f"我是LOL的第{Player.number}个玩家.我的名字是{self.name}.我来自{self.city}.我的等级是{self.level}")
    #定义一个升级方法
    def level_up(self):
        index_1 = Player.levels.index(self.level)
        if index_1 < len(Player.levels)-1:
            self.level = Player.levels[index_1 + 1]
    #获取一个武器的方法
    def get_weapon(self,weapon):
        self.weapon = weapon
    def show_weapon(self):
        return self.weapon.show_weapon()
    #类方法,以@classmethod装饰器标识,默认参数为cls,代表类本身
    @classmethod
    def get_players(cls):
        print(f"LOL游戏注册人数达到{cls.number}人")
miy = Player('miy',18,'成都','黄金')
miy.show()
Player.get_players()

6、变量作用域记忆口诀:
全局变量国家管,整个程序都能看
类属性是家族传,所有成员一起担
实例属性个人有,别人不能动我物
实例方法个人能,操作自己最方便
类方法办家族事,修改传统立规矩
静态方法工具类,不碰状态最独立

点击查看代码
class MyClass:
    class_attr = "类属性"
    
    def __init__(self, value):
        self.instance_attr = value  # 实例属性
    
    # 实例方法 - 可以访问实例属性和类属性
    def instance_method(self):
        return f"实例属性: {self.instance_attr}, 类属性: {self.class_attr}"
    
    # 类方法 - 可以访问类属性,不能访问实例属性
    @classmethod
    def class_method(cls):
        return f"类属性: {cls.class_attr}"
    
    # 静态方法 - 不能访问实例属性或类属性
    @staticmethod
    def static_method():
        return "我是静态方法,不访问类或实例属性"

7、静态方法

  • 类中不需要访问实例属性(self)或类属性(cls)的方法。它们与类和实例无关,更像是独立于类的普通函数,只是为了代码组织而放在类中
  • 优点:代码组织:将相关功能组织在一起、无需实例化:直接通过类名调用,节省内存、可读性:明确表明该方法不依赖实例状态、可测试性:更容易进行单元测试
  • 缺点:不能直接访问实例变量或类变量

8、面向对象的特点-继承

  • 子类可以继承父类的属性和方法,并可以扩展或修改父类的功能。
  • 子类的构造函数中与父类相同的属性,可以直接调用父类构造函数
    super().init(name, age) # 调用父类初始化方法
  • 子类的构造函数中可以直接使用父类进行初始化
    Animal__init__(self,name, age) #此时实例参数中需要携带self
点击查看代码
# wxPython框架使用了多重继承
class MyFrame(wx.Frame):
    def __init__(self):
        # 方法1:直接调用
        wx.Frame.__init__(self, None, title="Direct")
        # 这里wx.Frame可能有复杂的继承结构
        
        # 方法2:使用super
        super().__init__(None, title="Super")
        # super()会按照MRO找到正确的方法
点击查看代码
# 父类
class Animal:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def eat(self):
        return f"{self.name} 正在吃东西"
    
    def sleep(self):
        return f"{self.name} 正在睡觉"
    
    def make_sound(self):
        return "动物发出声音"

# 子类1:单继承
class Dog(Animal):
    def __init__(self, name, age, breed):
        super().__init__(name, age)  # 调用父类初始化方法
        self.breed = breed           # 新增属性
    
    # 方法重写(Override)
    def make_sound(self):
        return f"{self.name} 汪汪叫!"
    
    # 新增方法
    def fetch(self):
        return f"{self.name} 正在接飞盘"

# 子类2:多级继承
class GuideDog(Dog):
    def __init__(self, name, age, breed, license_number):
        super().__init__(name, age, breed)   # 调用父类初始化方法
        self.license_number = license_number # 新增属性
    
    def guide(self):
        return f"{self.name} 正在引导主人"
    
    def get_info(self):
        return f"导盲犬: {self.name}, 品种: {self.breed}, 执照: {self.license_number}"

# 使用示例
animal = Animal("小动物", 2)
print(animal.make_sound())  # 动物发出声音

dog = Dog("旺财", 3, "金毛")
print(dog.eat())           # 旺财 正在吃东西
print(dog.make_sound())    # 旺财 汪汪叫!
print(dog.fetch())         # 旺财 正在接飞盘

guide_dog = GuideDog("多多", 4, "拉布拉多", "GD2023001")
print(guide_dog.guide())   # 多多 正在引导主人
print(guide_dog.get_info()) # 导盲犬: 多多, 品种: 拉布拉多, 执照: GD2023001

9、面向对象的特点:多态

  • 同一操作作用于不同的对象,可以有不同的解释和执行结果。
  • 同一样方法在不同的子类中有不同的解释和结果,使用函数调用
点击查看代码
class Animal(object):
    def __init__(self,name,age,weight):
        self.name = name
        self.age = age
        self.weight = weight
    def speek(self):
        return f"动物的叫声"
#子类1
class Cat(Animal):
    def __init__(self,name,age,weight):
        super().__init__(name,age,weight)

    def speak(self):
        return f"{self.name}的叫声:喵~喵~"
#子类2
class Dog(Animal):
    def __init__(self,name,age,weight):
        super().__init__(name,age,weight)

    def speak(self):
        return f"{self.name}的叫声:汪~汪~"
class Bird(Animal):
    def __init__(self,name,age,weight):
        super().__init__(name,age,weight)

    def speak(self):
        return f"{self.name}的叫声:叽叽喳喳"
class Cow(Animal):
    def __init__(self,name,age,weight):
        super().__init__(name, age, weight)

    def speak(self):
        return f"{self.name}的叫声:哞~"

#处理多态的函数
def animal_speek(animal):
    """这个函数可以接受任何Animal子类的对象"""
    return animal.speak()
cat1 = Cat('小花',3,10)
dog1 = Dog('旺财',2.5,15)
bird1 = Bird('小翠',0.5,0.65)
cow1 = Cow('老黄',3.5,620)
print(animal_speek(cat1))
print(animal_speek(dog1))
print(animal_speek(bird1))
print(animal_speek(cow1))

10、面向对象的特点:封装

  • 数据(属性)和操作数据的方法(行为) 包装在一个单元(类)中,并对外隐藏实现的细节
  • 数据隐藏:保护数据不被外部直接访问
  • 接口暴露:提供公共方法访问数据
  • 约定俗成:以一个下划线 _ 开头,表示这是保护成员,但Python并不强制限制访问。
  • 真正私有:以双下划线 __ 开头,Python会进行名称修饰(name mangling),防止外部直接访问。
  • 查看方法装饰器:@property #获取变量使用的装饰器
  • 设置方法装饰器: @age.setter #修改变量的装饰器,函数名和获取变量的函数名一致
点击查看代码
#类的封装,隐藏类的实现,只暴露接口供用户调用
class User(object):
    citys = [
        '北京',  # 直辖市 - 首都
        '上海',  # 直辖市
        '天津',  # 直辖市
        '重庆',  # 直辖市
        '石家庄',  # 河北省
        '太原',  # 山西省
        '呼和浩特',  # 内蒙古自治区
        '沈阳',  # 辽宁省
        '长春',  # 吉林省
        '哈尔滨',  # 黑龙江省
        '南京',  # 江苏省
        '杭州',  # 浙江省
        '合肥',  # 安徽省
        '福州',  # 福建省
        '南昌',  # 江西省
        '济南',  # 山东省
        '郑州',  # 河南省
        '武汉',  # 湖北省
        '长沙',  # 湖南省
        '广州',  # 广东省
        '南宁',  # 广西壮族自治区
        '海口',  # 海南省
        '成都',  # 四川省
        '贵阳',  # 贵州省
        '昆明',  # 云南省
        '拉萨',  # 西藏自治区
        '西安',  # 陕西省
        '兰州',  # 甘肃省
        '西宁',  # 青海省
        '银川',  # 宁夏回族自治区
        '乌鲁木齐',  # 新疆维吾尔自治区
        '香港',  # 特别行政区
        '澳门',  # 特别行政区
        '台北'  # 台湾省(省会)
    ]

    def __init__(self, name, age,city):
        self._name = name   #公开变量
        self.__age = age    #私有变量
        self._city = city  #受保护的变量

    """
    把函数当做变量使用
    @property   #获取变量使用的装饰器
    def 变量名():
    @age.setter #修改变量的装饰器
    def 变量名():   #修改和获取的变量名保持一致
    """
    @property
    def name(self):
        return self._name
    @name.setter
    def name(self, name):
        try:
            if name == self._name:
                raise Exception('名字相同,无需修改')
            else:
                self._name = name
        except Exception as e:
            print(f"名字输入值不对:{e}")

    @property  #获取属性值的装饰器
    def age(self):
        return self.__age

    @age.setter  #修改属性的装饰器
    def age(self, age):
        try:
            if isinstance(age, int) and 0 <= age <= 100:
                self.__age = age
            else:
                raise Exception('年龄必须是0-100以内的正整数')
        except Exception   as e:
            print(f"年龄输入值不对:{e}")

    @property
    def city(self):
        return self._city
    @city.setter
    def city(self, city):
        try:
            if city in  User.citys:
                self._city = city
            else:
                raise Exception('必须是省会城市')
        except Exception as e:
            print(f"城市输入值不对:{e}")

    def show_infos(self):
        print(f"大家好,我是:{self.name} ,年龄是:{self.__age},我工作的城市是:{self._city}")

jack = User("jack", 18,'呼和浩特')
jack.show_infos()
print('*' * 30 +'名字方法验证'+'*' * 30)
jack.name = 'jack'
jack.name = 'tom'
print(f"jack更新后的名字是:{jack.name}")

print('*' * 30 +'年龄方法验证'+'*' * 30)
#print(jack._name)  #不建议这样使用
#print(jack.__age)
#jack.__show_infos()
#print(dir(jack))  #dir()内置函数打印对象或实例所有属性和方法
#print(jack.__dict__)
print(jack.age)
jack.age = '百岁'
jack.age = 29
print(f"jack更新后的年龄是:{jack.age}")
print('*' * 30 +'城市方法验证'+'*' * 30)
print(jack.city)
jack.city = '蒲城'
jack.city = '杭州'
print(f"jack更新后的城市是:{jack.city}")

11、魔法方法

  • Python中的魔法方法(也称为特殊方法或双下划线方法)是一种在类定义中使用的特殊命名的方法
  • 当python遇到某些内置操作时,他会尝试在对象上调用这些魔法方法
  • 操作包括但不限于算术运算、属性访问、类型转换等
点击查看代码
class User(object):
    def __init__(self,name,age):
        """初始化实例属性"""
        self.name = name
        self.age = age

    def __del__(self):
        """对象被销毁时调用"""
        print(f" {self.name}对象被销毁")


    def __str__(self):
        """对用户友好的字符串表示,print()和str()时调用"""
        return f"我的名字是:{self.name}"
    def __repr__(self):
        """对开发者友好的字符串表示,repr()和调试时调用"""
        return f"User('{self.name}', {self.age})"
    def __format__(self, format_spec):
        """格式化输出,format()时调用"""
        if format_spec == 'json':
            return f'{{"name":{self.name},"age":{self.age}}}'
        return str(self)

    def __add__(self, other):
        """对象拼接时被调用"""
        return self.name + other.name
    def __eq__(self, other):
        """定义 == 行为"""
        return self.name == other.name




jake = User('jake',29)
tom = User('tom',23)
print(jake.name)
print(str(jake))
print(jake)
print(10+23)
print('abc'+'edc')
print(jake + tom)
print(6==7)
print(jake==tom)
del jake

12、总结

  • 章节总结图
    image
  • dict 查看实例的所有属性
  • dir() 查看实例的所有属性和方法
  • init 类的初始化函数
  • @classmethod 装饰器,表示类方法
  • @staticmethod 装饰器,表示静态方法
  • @property 装饰器,把方法变成属性访问
  • @属性.setter 装饰器,设置私有属性的值
posted @ 2026-01-05 17:50  jake瑞  阅读(19)  评论(0)    收藏  举报