day 3 私有属性,私有方法,__del__
1.隐藏对象的属性
如果有一个对象,当需要对其进行修改属性时,有2种方法
- 对象名.属性名 = 数据 ---->直接修改
- 对象名.方法名() ---->间接修改
1)版本1:直接修改 对象的属性
class Dog: '''定义Dog类''' pass #创建一个对象 dog1 = Dog() dog1.age = 10 print(dog1.age)
2)版本2:通过方法,修改 对象的属性
class Dog: '''定义Dog类''' def set_age(self,new_age): self.age = new_age def get_age(self): return self.age dog1 = Dog() #dog1.age = -10 #print(dog1.age) dog1.set_age(10) print(dog1.get_age())
3)版本3:方法里面可以判断
class Dog: '''定义Dog类''' def set_age(self,new_age): if new_age >0 and new_age <100: self.age = new_age else: self.age = 0 def get_age(self): return self.age dog1 = Dog() #dog1.age = -10 #print(dog1.age) dog1.set_age(-10) print(dog1.get_age())
2.私有属性??? self.__age = 0
它是以属性命名方式来区分,如果在属性名前面加了2个下划线'__',则表明该属性是私有属性,否则为公有属性
为了更好的保存属性安全,即不能随意修改,一般的处理方式为
- 将属性定义为私有属性
- 添加一个可以调用的方法,供调用
class Dog: '''定义Dog类''' def __init__(self,new_name): self.name = new_name self.__age = 0 #定义了一个私有的属性,属性的名字是__age def set_age(self,new_age): if new_age >0 and new_age <100: self.__age = new_age else: self.__age = 0 def get_age(self): return self.__age dog1 = Dog("tom") #dog1.age = -10 #print(dog1.age) dog1.set_age(-10) print(dog1.get_age()) print(dog1.__age)
0 #可以通过公有方法调用私有属性 Traceback (most recent call last): File "02-隐藏对象的属性-私有属性.py", line 21, in <module> print(dog1.__age) AttributeError: 'Dog' object has no attribute '__age' #私有属性不能调用
#可以通过公有方法调用私有属性
#私有属性不能直接调用
3.私有方法 def __test1(self):
方法也是一样,方法名前面加了2个下划线的话表示该方法是私有的,否则为公有的
class Dog: def test1(self): print("----") def test2(self): print("#####") dog = Dog() dog.test1() dog.test2() #### 运行结果 ---- #####
2)版本2:
#### 私有方法 class Dog: #私有方法 def __test1(self): print("----") def test2(self): print("#####") dog = Dog() dog.test1() dog.test2() Traceback (most recent call last): File "03-私有方法.py", line 11, in <module> dog.test1() AttributeError: 'Dog' object has no attribute 'test1' #私有方法不能调用
3)版本3
实际开发: 先调用公有方法,然进行判断,符合条件,才能调用私有方法
class Dog: #私有方法 def __send_msg(self): print("正在发送短信。。") #公有方法 def send_msg(self,money): if money > 10000: self.__send_msg() else: print("余额不足,请充值") dog = Dog() dog.send_msg(1000000)
4.__del__ 方法 : 对象死亡时自动调用
1)版本1:程序自动退出,释放内存
class Dog: def __del__(self): print("----英雄over---") dog1 = Dog() dog2 = dog1 del dog1 print("======") #### 运行结果 ====== ----英雄over--- #程序退出,释放内存,自动执行del方法
2)版本2:对象没有人要调用,回收对象内存,自动执行
class Dog: def __del__(self): print("----英雄over---") dog1 = Dog() dog2 = dog1 del dog1 #不会调用__del__方法,因为这个对象 还有其他的变量指向它,即引用计算不是0 del dog2 #此时会调用__del__方法,因为没有变量指向它了 print("======") #如果在程序结束时,有些对象还存在,那么python解释器会自动调用他们的__del__方法来完成清理工作
#####运行结果‘’
----英雄over---
======
5.测量一个对象的引用计数方式
In [1]: import sys In [2]: #sys.getrefcount() In [3]: class T: ...: pass ...: In [4]: t = T() In [5]: sys.getrefcount(t) Out[5]: 2 In [6]: tt = t In [7]: sys.getrefcount(t) Out[7]: 3 In [8]: del tt In [9]: sys.getrefcount(t) Out[9]: 2 In [10]: del t In [11]: sys.getrefcount(t) --------------------------------------------------------------------------- NameError Traceback (most recent call last) <ipython-input-11-db87dac58216> in <module>() ----> 1 sys.getrefcount(t) NameError: name 't' is not defined