怪物卡车机器人
83.87MB · 2025-09-30
大家好,我是倔强青铜三。欢迎关注我,微信公众号:倔强青铜三。欢迎点赞、收藏、关注,一键三连!!!
欢迎来到 苦练Python第48天!今天我们来学习Python中类的私有变量。
在 Python 里,属性默认全是 public,就像把银行卡密码贴在额头上——谁都能改。
当你写了一个类给别人用:
class Person:
def __init__(self, money):
self.money = money # 公有,谁都能动
用户小手一抖:
p = Person(100)
p.money = -999999 # 余额瞬间蒸发
于是我们需要“私有变量”——给属性加一把锁,让外部“看不见、摸不着”。
_
——约定俗成Python 没有真正的 private
,但社区有默契:
带一个下划线的变量,请把它当私有,别直接碰!
class Wallet:
def __init__(self, cash):
self._cash = cash # 内部使用,外部别摸
外部依旧能访问,但 IDE 会画波浪线提醒你:
w = Wallet(50)
print(w._cash) # 能跑,但同事看了想打人
__
——名字改写(Name Mangling)Python 解释器会把 __var
改名成 _类名__var
,外部直接访问会 AttributeError。
class Wallet:
def __init__(self, cash):
self.__cash = cash # 真·隐藏
def spend(self, amount):
if amount <= self.__cash:
self.__cash -= amount
return True
return False
外部尝试:
w = Wallet(100)
print(w.__cash) # AttributeError: 'Wallet' object has no attribute '__cash'
print(w._Wallet__cash) # 100 —— 强行破解成功,但社死警告️
class Base:
_secret = "base"
class Sub(Base):
_secret = "sub"
print(Base()._secret) # base
print(Sub()._secret) # sub —— 被子类直接覆盖
class Base:
__secret = "base"
class Sub(Base):
__secret = "sub"
print(Base()._Base__secret) # base
print(Sub()._Sub__secret) # sub —— 两个名字并存,互不干扰
如果既想隐藏又想暴露只读接口,用 property
把变量包成“带门禁的房子”:
class Wallet:
def __init__(self, cash):
self.__cash = cash
@property
def cash(self):
"""只读属性"""
return self.__cash
def spend(self, amount):
if 0 < amount <= self.__cash:
self.__cash -= amount
return True
return False
使用姿势:
w = Wallet(100)
print(w.cash) # 100,外部只能看不能改
w.cash = 200 # AttributeError: can't set attribute
写法 | 能否直接访问 | 能否被子类覆盖 | 典型用途 |
---|---|---|---|
var | 公有属性 | ||
_var | (不推荐) | 内部使用/保护属性 | |
__var | 私有实现/防止覆盖 | ||
@property | (只读) | 安全暴露 getter |
Python 的“私有”靠 约定+改名,牢记:
_var
:兄弟别碰,碰了尴尬;__var
:真·隐藏,子类也找不到;@property
包一层!