Python类属性方法与实例属性方法解析
-
类属性和实体属性和私有属性和公共属性的关系。
这几个概念确实容易绕晕,但它们的关系其实特别清晰。咱们用刚才那个“奶茶店”的例子,把这四个概念一次性理顺。
你可以把它们拆解成两个维度:“是谁的东西”(归属) 和 “能不能随便碰”(权限)。
1. 归属维度:类属性 vs 实例属性(实体属性)
这是看这个属性属于谁。
-
类属性(Class Attribute):
-
归属:属于整个店铺(类本身)。
-
生活例子:奶茶店的招牌Logo、营业执照。不管你在北京还是上海开的这家店,Logo都是一样的,全店通用。
-
代码:写在类里面,方法外面。
class MilkTeaShop: shop_name = "一点点"
-
-
实例属性(Instance Attribute / 实体属性):
-
归属:属于具体的某一家门店(实例对象)。
-
生活例子:这家店的当日营业额、店长名字。每家店的营业额都不一样,互不干扰。
-
代码:写在
__init__里面,带self。def __init__(self): self.money = 0
-
2. 权限维度:公有属性 vs 私有属性
这是看外面的人能不能直接看/改。
-
公有属性(Public):
-
权限:谁都能看,谁都能改。
-
生活例子:店门口贴的菜单价格表。顾客可以直接看,甚至可以拿笔在上面写“太贵了”(虽然不道德,但物理上能做到)。
-
-
私有属性(Private):
-
权限:只有内部人员能碰,外面的人看不见。
-
生活例子:店里的秘方配比、进货成本。顾客是绝对看不到的,只有店长(类内部的方法)能看。
-
class MilkTeaShop: # 1. 公有类属性:招牌,大家都能看 brand = "快乐柠檬" # 2. 私有类属性:总部的秘密配方,只有内部能看 __headquarters_secret = "独家茶底配方" def __init__(self, location): # 3. 公有实例属性:门店地址,大家都能看 self.location = location # 4. 私有实例属性:这家店赚了多少钱,藏起来 self.__profit = 0 def sell(self, amount): # 内部方法可以修改私有实例属性 self.__profit += amount print(f"{self.location}店卖出一杯,赚了{amount}") # 测试关系 shop1 = MilkTeaShop("王府井店") shop2 = MilkTeaShop("中关村店") # 访问公有类属性(通过类或实例都能看) print(MilkTeaShop.brand) # 快乐柠檬 print(shop1.brand) # 快乐柠檬 # 访问公有实例属性 print(shop1.location) # 王府井店 # 试图访问私有实例属性(报错!) # print(shop1.__profit) # AttributeError
2.以加盟店名称和地址来描述类属性和实体属性
在这个场景下,我们把“加盟品牌总部”看作类(Class),把“街角的那家具体店面”看作实例(Instance)。
2.1. 类属性:品牌的统一规定
定义:属于整个品牌,所有加盟店共享同一份数据。
-
对应概念:加盟店名称(品牌名)。
-
生活例子:
你开了一家加盟店,不管是北京的、上海的还是广州的,你们挂的招牌都是“蜜雪冰城”。
-
这个“蜜雪冰城”的名字,不是你这家店自己发明的,而是总部(类)定好的。
-
如果总部改了名字(比如改成“雪王之家”),那么全中国所有加盟店的招牌都得跟着改。
-
class MilkTeaShop: # 这就是类属性:品牌名,大家一样 brand_name = "蜜雪冰城"
2.2. 实例属性(实体属性):店面的独立信息
定义:属于具体的某一家店,每家店的数据互不影响。
-
对应概念:加盟店地址。
-
生活例子:
你开在了“北京市朝阳区建国路88号”,我开在了“上海市黄浦区南京路100号”。
-
你的地址是你的,我的地址是我的,咱俩互不干扰。
-
你搬家了(改地址),不会影响我在上海的店。
-
class MilkTeaShop: brand_name = "蜜雪冰城" # 类属性 def __init__(self, address): # 这就是实例属性:地址,每家店不一样 self.address = address
2.3. 代码演示:
class MilkTeaShop: # 1. 类属性:品牌名称(大家的都一样) brand_name = "蜜雪冰城" def __init__(self, address): # 2. 实例属性:店铺地址(每一家都不一样) self.address = address # --- 场景模拟 --- # 第一家店:北京店 beijing_shop = MilkTeaShop("北京市朝阳区建国路88号") # 第二家店:上海店 shanghai_shop = MilkTeaShop("上海市黄浦区南京路100号") # 访问类属性(通过类名或实例都能访问,结果一样) print(f"品牌名:{MilkTeaShop.brand_name}") print(f"北京店品牌:{beijing_shop.brand_name}") # 输出:蜜雪冰城 print(f"上海店品牌:{shanghai_shop.brand_name}") # 输出:蜜雪冰城 print("-" * 20) # 访问实例属性(每家店都不一样) print(f"北京店地址:{beijing_shop.address}") # 输出:北京市朝阳区建国路88号 print(f"上海店地址:{shanghai_shop.address}") # 输出:上海市黄浦区南京路100号 print("-" * 20) # 修改类属性(影响全局) MilkTeaShop.brand_name = "雪王新家" print(f"改名后,北京店变成了:{beijing_shop.brand_name}") # 输出:雪王新家 print(f"改名后,上海店变成了:{shanghai_shop.brand_name}") # 输出:雪王新家 # 修改实例属性(只影响自己) beijing_shop.address = "北京市海淀区中关村1号" print(f"北京店搬家了:{beijing_shop.address}") print(f"上海店没动:{shanghai_shop.address}") # 上海店还是原来的地址
3.以加盟店名称和地址来描述类属性和实体属性
3.1. 类方法:总部的宏观调控
总部决定把全中国的店名从“蜜雪冰城”改成“雪王新家”。
代码特征:用 @classmethod装饰,第一个参数是 cls(指代总部这个类)。
完整代码演示:
class MilkTeaShop: # 类属性:总部的招牌 brand_name = "蜜雪冰城" def __init__(self, address): # 实例属性:店铺的地址 self.address = address # 1. 实例方法:具体店铺的行为 def open_shop(self): """这家具体的店开业了""" # 能访问实例属性(自己的地址) # 也能访问类属性(总部的品牌名) print(f"📍 位于 {self.address} 的 {self.brand_name} 开业啦!") # 2. 类方法:总部的决策 @classmethod def upgrade_brand(cls, new_name): """总部升级品牌名称""" # 只能访问/修改类属性,不能访问 self.address(因为它不属于任何具体店) cls.brand_name = new_name print(f"📢 总部通知:全品牌正式更名为 {cls.brand_name}!") # --- 场景模拟 --- # 创建两家具体的店(实例) shop_beijing = MilkTeaShop("北京市朝阳区") shop_shanghai = MilkTeaShop("上海市黄浦区") # 调用实例方法(具体店干活) shop_beijing.open_shop() shop_shanghai.open_shop() print("-" * 30) # 调用类方法(总部发话) MilkTeaShop.upgrade_brand("雪王之家") print("-" * 30) # 再次查看,发现两家店的名字都变了 shop_beijing.open_shop() shop_shanghai.open_shop()
3.2实例方法
加盟店的分成比例更改这个方法,还有某一个加盟店店长的选举改选方法
1. 加盟店的分成比例更改
归属:品牌总部(类 Class)
方法类型:类方法 (@classmethod)
-
为什么?
分成比例(比如:总部抽成10%还是20%)是全品牌通用的规则。它不是王府井店自己说了算的,也不是中关村店自己能改的,必须由总部(类)来统一发布命令。
-
代码逻辑:
修改的是类属性(
MilkTeaShop.divide_ratio)。一旦修改,所有加盟店(无论是已经存在的还是未来开的)都会自动应用新的分成比例。
2. 某一个加盟店店长的选举改选
归属:具体的某一家店(实例 Instance)
方法类型:实例方法 (Instance Method)
-
为什么?
店长是属于具体店面的。王府井店选张三当店长,跟上海店的店长是谁完全没有关系。这是单个实体的内部事务。
-
代码逻辑:
修改的是实例属性(
self.manager)。只会影响调用这个方法的那一家店。
class MilkTeaShop: # 类属性:全品牌的分成比例 divide_ratio = 0.1 # 默认总部抽成10% def __init__(self, address): self.address = address # 实例属性:这家店自己的店长 self.manager = "待定" # 1. 类方法:更改分成比例 @classmethod def change_divide_ratio(cls, new_ratio): """总部修改全品牌的分成比例""" cls.divide_ratio = new_ratio print(f"📢 总部通知:全品牌分成比例调整为 {new_ratio * 100}%") # 2. 实例方法:选举店长 def elect_manager(self, new_manager_name): """这家具体的店选举新店长""" old_manager = self.manager self.manager = new_manager_name print(f"🏪 {self.address}:店长由 {old_manager} 变更为 {new_manager_name}") # --- 场景模拟 --- # 创建两家店 shop1 = MilkTeaShop("北京王府井") shop2 = MilkTeaShop("上海南京路") # 初始状态 print(f"北京店店长:{shop1.manager}") # 待定 print(f"当前分成比例:{MilkTeaShop.divide_ratio}") # 0.1 print("-" * 30) # 场景一:总部修改分成比例(类方法) MilkTeaShop.change_divide_ratio(0.15) # 改成15% print(f"修改后,北京店适用的比例:{shop1.divide_ratio}") # 0.15 print(f"修改后,上海店适用的比例:{shop2.divide_ratio}") # 0.15 print("-" * 30) # 场景二:北京店自己选店长(实例方法) shop1.elect_manager("张三") shop2.elect_manager("李四") # 验证:上海店的店长还是李四,没受影响 print(f"最终北京店长:{shop1.manager}") # 张三 print(f"最终上海店长:{shop2.manager}") # 李四
一句话心法:
凡是“全行业通用”的(比如税率、品牌名、通用规则),用类方法。
凡是“个体户自家事”的(比如姓名、地址、自家老板),用实例方法。

浙公网安备 33010602011771号