面向对象
私有属性和私有方法
- 私有属性:在属性名前面加上两个下划线,那么这样定义的属性称为私有属性。私有属性只能在当前类里面使用,不能在类外面使用。
- 私有方法:在方法名前面加上两个下划线,那么这样定义的方法称为私有方法。私有方法只能在当前类里面使用,不能在类外面使用。
class Person(object):
def __init__(self, name, age):
# 公有属性,可以在类内部和类外面使用
self.name = name
# 私有属性,只能在类内部使用
self.__age = age
# 公有方法
def show(self):
# 在类内部,可以使用私有属性
print(self.name, self.__age)
# 在类内部,可以使用私有方法
print("年薪:", self.__money())
# 私有方法
def __money(self):
return "100万"
修改私有属性
- 修改私有属性不能直接通过对象进行修改,可以通过一个公有方法对私有属性进行修改,这样使得程序更加安全。
- 私有属性其实是对属性名进行了包装,包装格式:
_类名__属性名
,包装的目的不想让外界知道私有属性的名字。 - 注意:在类外使用“
对象.__属性
”不是修改私有属性,而是定义了一个对象的属性,属性名是“__属性
”。 - 扩展:查看对象的属性信息,使用魔法属性“
__dict__
”,对象(类).__dict__
,返回字典形式的属性信息(具体看下面实例)。 - 强制(非常规手段)修改私有属性的值:`对象._类名__属性名=新值
class Person(object):
def __init__(self, name, age):
# 给对象添加属性,设置属性的初始值
self.name = name
# 私有属性其实是对属性名进行了包装
# 包装格式:_类名__属性名,包装的目的不想让外界知道私有属性的名字
self.__age = age
# 提供公有方法设置私有属性, 目的:修改私有属性的时候比较安全
def set_age(self, new_age):
if (new_age >= 0) and (new_age <= 150):
self.__age = new_age
else:
print("成精了")
# 提供公有方法获取私有属性
def get_age(self):
return self.__age
p = Person("王美丽", 20)
print('初始化的姓名:', p.name)
# 修改公有属性
p.name = "李美丽"
print('修改后的姓名:', p.name)
# 错误演示,直接修改私有属性的值
# print(p.__age)
# 本意是要修改私有属性, 其实是添加的了一个__age这样的一个属性
# 这里不是添加了一个私有属性,只是一个普通的属性,
# 私有属性可以通过init方法进行添加
p.__age = 18
print('一不小心添加的变量:', p.__age)
# 非常规操作,直接使用包装后的私有属性,修改私有属性的值
p._Person__age = -18
print('非常规手段修改私有属性的值:', p._Person__age)
# 使用共有方法改变私有属性的值,使得程序更安全
p.set_age(-10)
age = p.get_age()
print(age)
# 查看对象的属性信息 -- 扩展
result = p.__dict__
print(result, type(result))
# {'name': '李美丽', '_Person__age': -18, '__age': 18} <class 'dict'>
子类不能使用父类的私有属性和私有方法
- 扩展:查看对象的属性和方法信息—
dir(对象)
,返回的是一个列表。
class Person(object):
def __init__(self, name, age):
# 给对象添加属性,设置属性的初始值
self.name = name
# 私有属性其实是对属性名进行了包装
# 包装格式:_类名__属性名,包装的目的不想让外界知道私有属性的名字
self.__age = age
# 公有方法
def show(self):
print("Person:", self.name)
# 私有方法
def __show_info(self):
print(self.name, self.__age)
class Student(Person):
def msg(self):
# 查看对象的属性信息
print(self.__dict__)
# 非常规手段, 获取父类的私有属性
print('非常规手段获取Person类的age私有属性的值:', self._Person__age)
# 非常规手段,调用父类的私有方法
# 查看对象的属性和方法信息--扩展, 返回的是一个列表
print(dir(self))
# ['_Person__age', '_Person__show_info',
# '__class__', '__delattr__', '__dict__',
# '__dir__', '__doc__', '__eq__', '__format__',
# '__ge__', '__getattribute__', '__gt__', '__hash__',
# '__init__', '__init_subclass__', '__le__', '__lt__',
# '__module__', '__ne__', '__new__', '__reduce__',
# '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__',
# '__str__', '__subclasshook__', '__weakref__', 'msg',
# 'name', 'show']
self._Person__show_info()
# Student没有init函数,用的是父类的
student = Student("李四", 20)
# 父类里面公有属性可以访问,私有属性不可以访问
print('父类的共有属性name:', student.name)
# print('不能方位父类的私有属性age:', student.__age)
# 父类的共有属性
student.show()
# 父类的私有属性
# student.__show_info()
# 总结: 子类不能使用父类的私有属性和私有方法
student.msg()