封装
封装是将属性和方法封装到一个抽象的类中。对象方法的细节都被封装在类的内部。
在对象的方法内部,是可以直接访问对象的属性的;同一个类创建的多个对象之间,属性是互不干扰的。
以下是房子添加家具的封装实例(把对象传给成员函数参数):
# -*- coding: utf-8 -*-
class HouseItem:
def __init__(self,name,area):
self.name=name
self.area=area
def __str__(self):
return "%s家具占地%d平"%(self.name,self.area)
task=HouseItem("桌子",3)
bed=HouseItem("床",6)
shafa=HouseItem("沙发",10)
class House:
def __init__(self,house_type,area):
self.house_type=house_type
self.area=area
self.free_area=area
self.item_list=[]
def __str__(self):
return ("户型为%s,面积为%d的房子中放下了这些家具%s,还剩下面积%.2f"%(self.house_type,self.area,self.item_list,self.free_area))
def add_item(self,item):
if self.free_area<item.area:
print("房子面积不够了,无法放下家具%s"%item.name)
return
print("把面积为%.2f的家具%s房子房子中"%(item.area,item.name))
self.item_list.append(item.name)
self.free_area-=item.area
hotel=House("旅馆",100)
hotel.add_item(task)
hotel.add_item(bed)
hotel.add_item(shafa)
print(hotel)
=========================================================================================
士兵实例(把类对象传给类属性):
# -*- coding: utf-8 -*-
class Gun:
def __init__(self,model):
self.model=model
self.bullet_count=0
def add_bullet(self,count):
if self.bullet_count==0:
self.bullet_count+=count
print("%s枪没子弹了,增加%d颗子弹"%(self.model,count))
return
print("%s枪还有子弹%d发,不用添加子弹"%(self.model,self.bullet_count))
def shoot(self):
print("pengpeng...")
self.bullet_count-=1
class Soldier:
def __init__(self,name):
self.name=name
self.gun=None
def fire(self):
if self.gun.model is None:
print("%s没有枪,请先配枪"%self.name)
return
self.gun.add_bullet(3)
self.gun.shoot()
print("开火了")
gun=Gun("ak47")
sold=Soldier("阿甘")
sold.gun=gun
sold.fire()
sold.fire()
sold.fire()
sold.fire()
sold.fire()
sold.fire()
sold.fire()
sold.fire()
sold.fire()
sold.fire()
身份运算符
身份运算符用于比较两个对象的内存地址shi'是否一致——是否是对同一个对象的引用
is判断两个对象是否是同一个;==判断引用变量的值是否相等
python中针对None比较时,建议使用is
运算符 | 描述 | 实例 |
---|---|---|
is | is 是判断两个标识符是不是引用同一个对象 | x is y,类似 id(x) == id(y) |
is not | is not 是判断两个标识符是不是引用不同对象 | x is not y,类似 id(a) != id(b) |
以下是一些其他的理解
class Cat:
def __init__(self):
self.name="汤姆"
def eat(self):
print("%s爱吃鱼"%self.name)
def drink(self):
print("%s要喝水"%self.name)
tom=Cat() # 默认把对象tom赋给self,self=tom
tom.eat()
tom.drink()
lazy_cat=Cat()
lazy_cat.eat()
=================================================================================
# -*- coding: utf-8 -*-
class Cat:
# 1、self=tom
# 2、self=lazy_cat
def __init__(self,name_str): # self=tom,name_str="tom" ||| self=lazy_cat,name="大懒猫"
# 1、tom.name="汤姆" ---》 在tom的对象空间里,创建变量 存储“汤姆”
# 2、lazy_cat.name="懒猫"----》在lazy_cat的对象空间里面
print(self,id(self)) # 打开和关闭,试试看
self.name=name_str
def eat(self):
print("%s爱吃鱼"%self.name)
def drink(self):
print("%s要喝水"%self.name)
print(Cat("汤姆"),id(Cat("汤姆"))) # tom=Cat()默认调用__init__(tom,"汤姆") 加上默认的参数和传入的数据
# print("***********************************") # 前面创建了一次对象,立马删除;后面又创建了一次对象
# 会使用之前的对象内存。如果在这之间有其他语句,那么之前创建的
#内存对象会彻底销毁;之后的创建对象会创建新的内存对象空间
# 对象空间是在内存中吗
# Cat("11") # a=1,a和1分别存储在哪里,内存,磁盘
tom=Cat("汤姆")
print(tom)
print(id(tom))
# tom.eat()
# tom.drink()
# lazy_cat=Cat("懒猫")
# lazy_cat.eat()
a=1
print(id(a),id(1))
a=2
print(id(a),id(2))
"""
同时,如果没有任何变量指向内存空间的某个值,这个值称为垃圾数据,
系统会自动将其删除,回收它占用的内存空间。
也可以使用del 命令 删除变量,
但是删除之后就不能再使用了。否则会报错:变量没有定义。
0x000002B0F307C128才是地址
2959014871336是系统给的临时id地址,id是唯一的。
一块对象空间的地址赋值给a,a可能是2959014871448,a被回收了,再把对象空间地址赋值给b,2959014871448,a和b存储的地址可能
不同,但是都是指向0x000002B0F307C128地址。0x000002B0F307C128是绝对地址,2959014871448是临时定义的一串唯一地址,这一串
唯一地址没被回收的时候,0x000002B0F307C128赋值给c,id(c)也等于2959014871448。
a被回收后,0x000002B0F307C128赋值给d,id(d)变为了其他值。
"""
=====================================
# -*- coding: utf-8 -*-
class Cat:
def __init__(self,new_name):
self.name=new_name
print("%s来了"%self.name)
def __del__(self): # 程序(代码)一走完就调用
print("%s去了"%self.name) # object中没有__del__()方法
tom=Cat("汤姆")
print(tom.name)
del tom # del关键字可以删除一个对象
# a=object()
# a.
print("-------------")
# -*- coding: utf-8 -*-
class Cat:
def __init__(self,new_name):
self.name=new_name
print("%s来了"%self.name)
def __del__(self): # 程序(代码)一走完就调用
print("%s去了"%self.name)
def __str__(self): # self=tom
return "我是小猫" # 返回值必须存在
tom=Cat("汤姆") # 创建了一个对象tom,对象传参self=tom
# 在类外部,tom.成员;在类中,self.成员
print(tom.name)
print(tom) # print(tom.__str__()) print(地址值)
# __str__(tom)必须要有返回值
# del tom # del关键字可以删除一个对象
========================
***********************************************************************************************************************
私有属性和方法
应用场景
- 在实际开发中,对象 的 某些属性或方法 可能只希望 在对象的内部被使用,而 不希望在外部被访问到
- 私有属性 就是 对象 不希望公开的 属性
- 私有方法 就是 对象 不希望公开的 方法
定义方式
- 在 定义属性或方法时,在 属性名或者方法名前 增加 两个下划线,定义的就是 私有 属性或方法
伪私有属性和方法
Python 中,并没有 真正意义 的 私有
在给 属性、方法 命名时,实际是对 名称 做了一些特殊处理,使得外界无法访问到
处理方式:在 名称 前面加上 _类名 => _类名__名称
# 私有属性,外部不能直接访问到
print(xiaofang._Women__age)
# 私有方法,外部不能直接调用
xiaofang._Women__secret()
********************************************************************************************************************************