Python中的封装,python对函数进行封装
本文主要介绍python中面向对象封装的细节。在Python中,也有对对象的封装操作,对外界只提供固定的访问方式,不能访问其内部私有属性和方法。具体如下,可以参考需要的小伙伴。
00-1010一个封装的概念II _属性和方法的私有化_ by _ 1。单下划线_2。双下划线__3。在子类III中访问父类的私有属性和方法。访问和修改类1的私有属性和方法。自定义公共方法2。财产
目录
其实包装在我们的生活中无处不在,比如电视机、电脑、手机等物品。通常我们只能看到它的外在造型,使用它们提供的功能,却看不到它内部复杂的硬件构成。这些都是打包好的,不能被我们看到,以免我们的一些“特殊”操作使其无法正常工作。编程来源于生活。在python中,也有对对象的封装操作,使其只对外界提供固定的访问方式,而不能访问其内部私有属性和方法。python中的封装一般是指类属性和方法的封装,即类属性的私有化和类方法的私有化,下面的总结中会详细介绍。
一 封装的概念
二 _ 和__ 对属性和方法的私有化
当类中的属性和方法以_单下划线开头时,意味着它们是该类的受保护变量和方法。根据编码约定,它们不希望被外部访问。但是如果要访问,就不会报错。
如下:
A类():
# _声明是保护属性和保护方法。
_name=张三
def __init__(self):
自我。_年龄=23岁
定义_方法(自身):
打印(我叫{},今年{}岁。格式(自我。_name,self。_年龄))
if __name__==__main__:
a=A()
#打印a类目录
打印(a. __目录_ _())
#访问保护变量和保护方法
打印(姓名)
形容词(adjective的缩写)_方法()
输出结果:
[_age , __module__ , _name , __init__ , _ _ method , __dict__ , __weakref__ , __doc__ , __repr__ , __hash__ , __str__ , __getattribute__ , __setattr__ , __delattr__ , __lt__ , __le__ , __eq__ ,,
张三
我叫张三,今年23岁。
可以看出,以_单下划线开头的属性和方法实际上是可以在类外访问的,但是按照约定,当我们看到这样的属性和方法时,不应该在类外访问。
1. 单下划线_
尽管以单下划线开头的上述属性和方法受到保护,但仍然可以从外部访问它们。当你看到以双下划线_ _开头的属性和方法时,请记住它们是类的私有属性和私有方法。在类之外和子类中访问类的属性和方法的方法不能被访问或修改,如下所示
>
class B():#__ 声明是私有化的
__name = 张三
def __init__(self):
self.__age = 23
self.__luange = python
def __method(self):
#私有方法
print("我叫{},今年{}岁,我喜欢{}。".format(self.__name, self.__age, self.__luange))
def fun(self):
#公有方法
print("this is a public method")
if __name__ == __main__:
b = B()
#打印类B的dir
print(b.__dir__())
#访问类B的私有属性和私有方法
b.fun()
print(b.__name, b.__age, b.__luange)
b.__method()
输出结果:
>>>
['_B__age', '_B__luange', '__module__', '_B__name', '__init__', '_B__method', 'fun', '__dict__', '__weakref__', '__doc__', '__repr__', '__hash__', '__str__', '__getattribute__', '__setattr__', '__delattr__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__new__', '__reduce_ex__', '__reduce__', '__subclasshook__', '__init_subclass__', '__format__', '__sizeof__', '__dir__', '__class__']
this is a public method
Traceback (most recent call last):
File "C:/Users/admin/python-learning/python学习文件/python基础/python类封装.py", line 56, in <module>
print(b.__name, b.__age, b.__luange)
AttributeError: 'B' object has no attribute '__name'
从结果可以看出,访问类B的公有方法fun()
是正常输出的,但是当我们访问私有属性name时就抛错:类B没有name属性。上面单下划线时,我们打印类A的dir,可以看到类A的name
属性和method
方法在dir里面是下面这样的
上面我们也打印了类B的私有属性和私有方法,如下:
可以看到私有属性和私有方法都变成了_B__属性和_B__方法的形式,所以我们在上面以__ name或者name的形式去访问是报错的,其实我们如果以 类名(). _ 类名__ 属性(实例属性)或者类名. _ 类名__ 属性(类属性)的形式去访问,还是会访问成功的。如下
class B():#__ 声明是私有化的
__name = 张三
def __init__(self):
self.__age = 23
self.__luange = python
def __method(self):
#私有方法
print("我叫{},今年{}岁,我喜欢{}。".format(self.__name, self.__age, self.__luange))
def fun(self):
#公有方法
print("this is a public method")
if __name__ == __main__:
b = B()
#打印类B的dir
print(b.__dir__())
#访问类B的私有属性和私有方法
b.fun()
print(B._B__name, b._B__age, b._B__luange)
b._B__method()
结果如下:
>>>
['_B__age', '_B__luange', '__module__', '_B__name', '__init__', '_B__method', 'fun', '__dict__', '__weakref__', '__doc__', '__repr__', '__hash__', '__str__', '__getattribute__', '__setattr__', '__delattr__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__new__', '__reduce_ex__', '__reduce__', '__subclasshook__', '__init_subclass__', '__format__', '__sizeof__', '__dir__', '__class__']
this is a public method
张三 23 python
我叫张三,今年23岁,我喜欢python。
3. 子类中访问父类的私有属性和私有方法
子类无法访问父类的私有属性和私有方法:
class B():#__ 声明是私有化的
__name = 张三
def __init__(self):
self.__age = 23
self.__luange = python
def __method(self):
#私有方法
print("我叫{},今年{}岁,我喜欢{}。".format(self.__name, self.__age, self.__luange))
def fun(self):
#公有方法
print("this is a public method")
class C(B):
def __init__(self):
super().__init__()
def fun1(self):
#访问父类B的私有属性和私有方法
print(self.__name, self.__age, self.__luange)
self.__method()
if __name__ == __main__:
c = C()
c.fun1()
输出结果:
>>>
AttributeError: 'C' object has no attribute '_C__name'
AttributeError: 'C' object has no attribute '_C__method'
可以看出子类也是无法访问父类的私有属性和私有方法的。
当子类中的的属性和方法与父类的私有属性,私有方法同名时,不会覆盖父类的私有属性和私有方法。
class B():#__ 声明是私有化的
__name = 张三
def __init__(self):
self.__age = 23
self.__luange = python
def __method(self):
#私有方法
print("我叫{},今年{}岁,我喜欢{}。".format(self.__name, self.__age, self.__luange))
def fun(self):
#公有方法
print("this is a public method")
class C(B):
__name = 李四
def __init__(self):
super().__init__()
self.__age = 24
self.__luange = C++
def fun1(self):
#访问父类B的私有属性和私有方法
print(self.__name, self.__age, self.__luange)
self.__method()
def __method(self):
#类C的私有方法,与父类方法同名,但不重写父类方法
print("我叫{},今年{}岁,我喜欢{}。".format(self.__name, self.__age, self.__luange))
#调用父类的私有方法
B()._B__method()
if __name__ == __main__:
c = C()
#访问类C的私有方法
c._C__method()
结果如下:
>>>
我叫李四,今年24岁,我喜欢C++。
我叫张三,今年23岁,我喜欢python。
可以看到,子类C并没有重写父类B的__method()方法。这是为什么呢?我们打印一下B和C的dir,如下:
>>>
['_B__age', '_B__luange', '_C__age', '_C__luange', 'fun1',
'_C__method', '__doc__', '_B__name', '_B__method', '_C__name', ...]
可以看到,在类C的dir中,父类B的私有属性和私有方法是以 _B__属性(方法)存在的,二类C自己的私有属性和私有方法是以_C__属性(方法)存在的,即类的私有属性和私有方法会以_类名_属性(方法)的形式存在dir中,所以当子类的属性和方法与父类的私有属性和私有方法同名时,并不会覆盖重写。
三 访问及修改类的私有属性和私有方法
类通过对属性和方法的私有化,可以对其起到封装保护作用。但是,当外部需要访问和改变时怎么办呢?就像电视机,电脑也会对外提供固定的接口。
上面,虽然我们可以通过类名(). _ 类名__ 属性(实例属性)或者类名. _ 类名__ 属性(类属性)的形式去访问类的私有属性和私有方法,但是这是违反编程规范的,不支持这么做,就像不会拆开电视机对其操作一样。
正确对类的私有属性和私有方法进行访问修改的一般有两种发方法,如下:
1. 自定义公有方法
class D():__name = 张三
def __init__(self):
self.__age = 23
self.__luange = python
def __method(self):
print("我叫{},今年{}岁,我喜欢{}。".format(self.__name, self.__age, self.__luange))
def get_value(self):
return self.__name, self.__age, self.__luange
def get_method(self):
self.__method()
def set_value(self, name, age, luange):
self.__name, self.__age, self.__luange = name, age, luange
if __name__ == __main__:
d = D()
#通过get_value方法访问私有属性
print(d.get_value())
#通过get_method方法访问私有方法
print(= * 30)
d.get_method()
#通过set_value方法修改私有属性
print(=*30)
print(d.get_value())
d.set_value(王二麻子, 25, Linux)
print(d.get_value())
d.get_method()
输出结果:
>>>
('张三', 23, 'python')
==============================
我叫张三,今年23岁,我喜欢python。
==============================
('张三', 23, 'python')
('王二麻子', 25, 'Linux')
我叫王二麻子,今年25岁,我喜欢Linux。
可以看到,我们通过自定义的的get_value(),get_method()以及set_value()方法就实现了对私有属性和私有方法的访问和修改。
2. property
property一般有两个作用,如下:
- 作为装饰器,@property 将类的方法转为只读的类属性
- property 重新实现一个属性的 getter 和 setter 方法
来看看下面这个E类,如下:
class E():__name = 张三
def __init__(self):
self.__age = 23
self.__luange = python
def __method(self):
print("我叫{},今年{}岁,我喜欢{}。".format(self.__name, self.__age, self.__luange))
def get_value(self):
return self.__name
def set_value(self, name):
self.__name = name
getValue = property(get_value, set_value)
@property
def get_method(self):
self.__method()
if __name__ == __main__:
e = E()
#访问
print(e.getValue)
e.get_method
#修改
e.getValue = 王二
print(e.getValue)
结果:
>>>
张三
我叫张三,今年23岁,我喜欢python。
王二
可以看到,我们将get_value
和set_value
方法传入property后,类方法就转换成类属性,并赋值给getValue变量。此时e.getValue就是只读,即get_value方法,e.value = ‘王二’ 就是修改,即get_value
方法。同一,通过@propert,将get_method方法,变成了属性。
下面property
重新实现一个属性的 getter 和 setter 方法,不同于上面的写法,较上面常用。
class E():__name = 张三
def __init__(self):
self.__age = 23
self.__luange = python
def __method(self):
print("我叫{},今年{}岁,我喜欢{}。".format(self.__name, self.__age, self.__luange))
@property
def name(self):
return self.__name
@name.setter
def name(self, name):
self.__name = name
if __name__ == __main__:
e = E()
#访问
print(e.name)
#修改
print("修改前:", e.name)
e.name = 隔壁老王
print("修改后:", e.name)
输出结果:
>>>
张三
修改前: 张三
修改后: 隔壁老王
上面是首先把name方法送给propert装饰器进行装饰,然后调用装饰后的setter方法,即可实现对私有属性进行修改。
到此这篇关于Python面向对象中的封装详情的文章就介绍到这了,更多相关Python封装内容请搜索盛行IT软件开发工作室以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT软件开发工作室!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。