为了让定义的数据类型,能使用不同的应用场景,一般情况下我们 要对当前类型的所有属性进行封装处理。
封装属性之后,会提供访问属性数据的set/get方法,书写过程中方法中不需要添加任何限制条件,只是预留了可以添加限制条件的方法而已,后期根据项目需求进行限制和条件的完善。
class Goods:
def __init__(self, name, price):
self.__name = name
self.__price = price
def set_name(self, name):
self.__name = name
def get_name(self):
return self.__name
def set_price(self, price):
self.__price = price
def get_price(self):
return self.__price
car = Goods("奥拓", 18000)
print("car的价格:", car.get_price()) # 1800
# 如果通过 对象的引用变量.属性 直接赋值,该属性又不是类型中定义的属性
# 这个属性就是 单独属于这个对象 的扩展属性。
car.__price = 20000
print("car的价格", car.__price, "---", car.get_price()) # 20000 ————18000
# 扩展属性,属于对象car
car.__color = "红色"
print(car.__color) # 红色
# car2 = Goods("奥迪", 300000) # 报错
# print(car2.__color)
"""
上面方法可以扩展属性,但是,这样的扩展方式,破坏了原有的封装语法,让代码的可读性出现了严重的下降
解决方案如下:在类型中,定义好~该对象可能出现的属性,其他任何扩展属性就不能添加了。
"""
class Pet:
"""宠物类型:限制该类型只能出现哪些属性"""
# 限制该类型的对象,只能拥有下面列表中出现的属性
__slots__ = ['__name', '__age', '__gender', 'color']
def __init__(self, name, age):
self.__name = name
self.__age = age
self.__gender = gender
def set_name(self, name):
self.__name = name
def get_name(self):
return self.__name
def set_age(self, age):
self.__age = age
def get_age(self):
return self.__age
p = Pet("tomcat", 3)
print(p.get_name(), p.get_age()) # tomcat 18
# 扩展属性
p.color = "灰色"
print(p.get_name(), p.get_age(), p.color)
p.email = "tomcat@cat.com" # 报错
print(p.email)