共计 3222 个字符,预计需要花费 9 分钟才能阅读完成。
一、限制访问
-
属性类型
-
公有
在内部和外部均可访问
目前为止,正常定义在构造函数中
-
私有
- 如果要让内部属性不被外部访问,可以把属性名称前加上两个下滑线
- python 中实例的变量以__开头,就变成了一个私有属性(private),只能在类的内部访问,无法在类的外部直接访问
- 属性前加一个下划线,这样的属性约定俗成的表示请把我看成私有的属性来用(虽然可以在类的外部直接访问),不要在外部直接访问
-
特殊
在 python 中,变量名类似
__xxx__
的属于特殊变量,特殊变量是可以直接在外部访问的,不是私有属性
-
-
定义
class Person(object): def __init__(self, name, age, sex, money, faceValue, word): self.name = name self.age = age self.sex = sex # 不能再外部直接访问__money 的原因是 python 解释器对外把__money 属性变为_Person__money。所以任然可以使用_Person__money 来直接访问,但是强烈建议不要这么来用,因为不同版本的 python 解释器可能会把__money 改成不同的名字 self.__money = money self._faceValue = faceValue self.__word__ = word
-
使用
class Person(object): def __init__(self, name, age, sex, money, faceValue, word): self.name = name self.age = age self.sex = sex self.__money = money self._faceValue = faceValue self.__word__ = word # 定义公有方法间接访问私有属性 def getMoney(self): return self.__money def setMoney(self, value): self.__money = value def getFaceValue(self): return self._faceValue def setFaceValue(self, value): self._faceValue = value def play(self): print("---------play") self.__run() # 私有方法,只能在类的内部调用 def __run(self): print("----------run")
per = Person("liudh", 55, "男", 100, 99, "good") # 在类的外部访问对象属性 print(per.name) # 无法在类的外部直接访问私有属性 # print(per.__money) # 通过调用公有方法间接访问私有属性 print(per.getMoney()) per.setMoney(10) print(per.getMoney()) # print(per._Person__money) #以后不要这么使用 # 无法在类的外部直接调用私有方法 # per.__run() per.play() # print(per._faceValue) # 不要这么用 print(per.getFaceValue()) print(per.__word__)
二、@property
-
目的
让访问私有属性像访问公有属性那样方便,让私有属性可以使用点语法
-
访问私有属性的原始方式:使用公有方法访问私有属性
class Person(object): def __init__(self, name, age, sex, money): self.name = name self.age = age self.sex = sex self.__money = money def getMoney(self): return self.__money def setMoney(self, value): self.__money = value 通过访问公有方法间接访问私有属性 print(per.getMoney()) per.setMoney(1000) print(per.getMoney())
-
想让访问私有属性的方式类似访问普通属性
使用 @property 让私有属性可以使用点语法。但本质上还是调用公有方法访问的私有属性,只不过看起来比较美丽
class Person(object): def __init__(self, name, age, sex, money): self.name = name self.age = age self.sex = sex self.__money = money # 取值,当 对象.money 时相当于访问了该方法 # 函数名为私有属性去掉下划线的部分 @property def money(self): return self.__money # 赋值,当 对象.money = 值 时相当于调用该方法,“值”当做参数传递进来(value = "值") @money.setter def money(self, value): self.__money = value per = Person("liudh", 55, "男", 100) # 访问私有属性的方式类似访问普通属性 print(per.money) per.money = 200 print(per.money)
三、动态给实例对象添加属性与方法
-
准备代码
class Person(object): def __init__(self, name): self.name = name def say(self): print("%s is a good man"%(self.name)) per1 = Person("liudh") per2 = Person("daolang") per1.say() per2.say()
-
增加对象属性
# 增加对象属性(实例化一个对象后,可以给对象绑定任意的属性和方法) per1.age = 55 # 如果属性不存在则变为增加属性 print(per1.age) # 给对象增加对象属性,只会给当前对象增加 # print(per2.age) #per2 没有 age 属性
-
增加类属性
# 每个对象同时增加 Person.city = "北京" print(per1.city) print(per2.city)
-
增加对象方法
-
增加的既不是对象方法也不是类方法,有点类似静态方法
# def run(): # print("--------run") # per1.run = run # per1.run()
-
增加的确实是对象方法,但是需要手动给形参 self 传递参数
# def run(self): # print("------------run") # self.say() # per1.run = run # per1.run(per1)
-
合适的方式
def run(self): print("------------run") self.say() from types import MethodType per1.run = MethodType(run, per1) per1.run()
-
-
添加类方法
def play(cls): print("-----play") from types import MethodType Person.play = MethodType(play, Person) Person.play()
四、使用__slots__属性限制增加
-
思考
想要限制实例的属性,不让对象随意添加属性,只能添加一些我们规定
-
解决
在定义类时,定义一个
__slots__
特殊属性, 限制该类实例能添加的属性class Person(object): __slots__ = ("name", "age", "sex", "money") def __init__(self, name): self.name = name def say(self): print("%s is a good man"%(self.name))
-
使用
per = Person("liudh") per.age = 55 per.sex = "男" # per.faceValue = 100 # Person.city = "北京"
正文完
星哥玩云-微信公众号