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 装饰器,设置私有属性的值


浙公网安备 33010602011771号