Python类属性方法与实例属性方法解析

  1. 类属性和实体属性和私有属性和公共属性的关系。

这几个概念确实容易绕晕,但它们的关系其实特别清晰。咱们用刚才那个“奶茶店”的例子,把这四个概念一次性理顺。

你可以把它们拆解成两个维度:“是谁的东西”(归属)​ 和 “能不能随便碰”(权限)

1. 归属维度:类属性 vs 实例属性(实体属性)

这是看这个属性属于谁

  • 类属性(Class Attribute)

    • 归属:属于整个店铺(类本身)。

    • 生活例子:奶茶店的招牌Logo营业执照。不管你在北京还是上海开的这家店,Logo都是一样的,全店通用。

    • 代码:写在类里面,方法外面。class MilkTeaShop: shop_name = "一点点"

  • 实例属性(Instance Attribute / 实体属性)

    • 归属:属于具体的某一家门店(实例对象)。

    • 生活例子:这家店的当日营业额店长名字。每家店的营业额都不一样,互不干扰。

    • 代码:写在 __init__里面,带 selfdef __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}") # 李四

一句话心法:

凡是“全行业通用”的(比如税率、品牌名、通用规则),用类方法

凡是“个体户自家事”的(比如姓名、地址、自家老板),用实例方法

 

posted @ 2026-05-22 16:07  szmtjs10  阅读(12)  评论(0)    收藏  举报