Python中的封装,python对函数进行封装,Python面向对象中的封装详情

Python中的封装,python对函数进行封装,Python面向对象中的封装详情

本文主要介绍python中面向对象封装的细节。在Python中,也有对对象的封装操作,对外界只提供固定的访问方式,不能访问其内部私有属性和方法。具体如下,可以参考需要的小伙伴。

目录

一个封装的概念II _属性和方法的私有化_ _ 1。单下划线_2。双下划线__3。访问子类III中父类的私有属性和方法。访问和修改类1的私有属性和方法。自定义公共方法2。财产

一 封装的概念

其实包装在我们的生活中无处不在,比如电视机、电脑、手机等物品。通常我们只能看到它的外在造型,使用它们提供的功能,却看不到它内部复杂的硬件构成。这些都是打包好的,不能被我们看到,以免我们的一些“特殊”操作使其无法正常工作。编程来源于生活。在python中,也有对对象的封装操作,使其只对外界提供固定的访问方式,而不能访问其内部私有属性和方法。python中的封装一般是指类属性和方法的封装,即类属性的私有化和类方法的私有化,下面的总结中会详细介绍。

二 _ 和__ 对属性和方法的私有化

1. 单下划线_

当类中的属性和方法以_单下划线开头时,意味着它们是该类的受保护变量和方法。根据编码约定,它们不希望被外部访问。但是如果要访问,就不会报错。

如下:

A类():

# _声明是保护属性和保护方法。

_name='张三'

def __init__(self):

自我。_年龄=23岁

def _method(自身):

打印('我叫{},今年{}岁'。格式(自我。_name,self。_年龄))

if __name__=='__main__ ':

a=A()

#打印a类目录

打印(a. __目录_ _())

#访问保护变量和保护方法

打印(姓名)

a._方法()

输出结果:

['_age ',' __module__ ',' _name ',' __init__ ',' _ _ method ',' __dict__ ',' __weakref__ ',' __doc__ ',' __repr__ ',' __hash__ ',' __str__ ',' __getattribute__ ',' __setattr__ ',' __delattr__ ',' __lt__ ',' __le__ ',' __eq__ ',','

张三

我叫张三,今年23岁。

可以看出,以_单下划线开头的属性和方法实际上是可以在类外访问的,但是按照约定,当我们看到这样的属性和方法时,不应该在类外访问。

2. 双下划线__

尽管以单下划线开头的上述属性和方法受到保护,但仍然可以从外部访问它们。当你看到以双下划线_ _开头的属性和方法时,请记住它们是类的私有属性和私有方法。在类之外和子类中访问类的属性和方法的方法不能被访问或修改,如下所示

B类():

# _ _宣布私有化

__name='张三'

def __init__(self):

自我。_ _年龄=23岁

自我。__luange='python '

def __method(自我):

#私有方法

Print('我叫{},今年{}岁,我喜欢{}。'。格式(自我。__name,self。_ _年龄,自我。_ _栾格))

定义乐趣(自我):

#公共方法

打印(“这是一个公共方法”)

if __name__=='__main__ ':

b=B()

#打印b类目录

print(b.__dir__())

#访问b类的私有属性和私有方法。

b .乐趣()

打印(b . _ _姓名,b . _ _年龄,b . _ _栾)

b._ _方法()

输出结果:

['_B__age ',' _B__luange ',' __module__ ',' _B__name ',' __init__ ',' _B__method ',' __dict__ ',' __weakref__ ',' __doc__ ',' __repr__ ',' __hash__ ',' __str__ ',' __getattribute__ ',' __setattr__ ',' __delattr__ ',' __lt__ '

这是一个公共方法

回溯(最近一次呼叫):

文件“c:/users/admin/python-learning/python learning files/python basics/python class encapsulation . py”,第56行,在模块中

打印(b . _ _姓名,b . _ _年龄,b . _ _栾)

attribute错误:“B”对象没有属性“__name”

从结果中可以看出,B类的公共方法fun()是正常输出的,但是当我们访问私有属性name时,抛出一个错误:B类没有name属性。当上面有下划线时,我们打印A类的dir,可以看到在dir中A类的name属性和方法如下

上面我们也打印了类B的私有属性和私有方法,如下:

可以看出,私有属性和私有方法都是以_B__ attributes和_B__ methods的形式出现,所以我们以__ name或name的形式访问它们是错误的。事实上,如果我们以类名()的形式访问它们。_ class name _ _ attribute(实例属性)或类名。_ class name _ _ attribute(类属性),我们还是会成功的。如下

B类():

# _ _宣布私有化

__name='张三'

def __init__(self):

自我。_ _年龄=23岁

自我。__luange='python '

def __method(自我):

#私有方法

Print('我叫{},今年{}岁,我喜欢{}。'。格式(自我。__name,self。_ _年龄,自我。_ _栾格))

定义乐趣(自我):

#公共方法

打印(“这是一个公共方法”)

if __name__=='__main__ ':

b=B()

#打印b类目录

print(b.__dir__())

#访问b类的私有属性和私有方法。

b .乐趣()

打印(姓名,年龄,性别)

b._ B _ _方法()

结果如下:

['_B__age ',' _B__luange ',' __module__ ',' _B__name ',' __init__ ',' _B__method ',' __dict__ ',' __weakref__ ',' __doc__ ',' __repr__ ',' __hash__ ',' __str__ ',' __getattribute__ ',' __setattr__ ',' __delattr__ ',' __lt__ '

这是一个公共方法

张三23蟒

我的名字叫张三。我今年23岁。我喜欢python。

3. 子类中访问父类的私有属性和私有方法

子类无法访问父类的私有属性和私有方法:

B类():

# _ _宣布私有化

__name='张三'

def __init__(self):

自我。_ _年龄=23岁

自我。__luange='python '

def __method(自我):

#私有方法

Print('我叫{},今年{}岁,我喜欢{}。'。格式(自我。__name,self。_ _年龄,自我。_ _栾格))

定义乐趣(自我):

#公共方法

打印(“这是一个公共方法”)

丙类(乙类):

def __init__(self):

超级()。__init__()

def fun1(自身):

#访问父类b的私有属性和私有方法。

打印(自我。__name,self。_ _年龄,自我。_ _栾格)

自我。_ _方法()

if __name__=='__main__ ':

c=C()

c.fun1()

输出结果:

attribute错误:“C”对象没有属性“_C__name”

attribute错误:“C”对象没有属性“_C__method”

可见子类是无法访问父类的私有属性和私有方法的。

当子类中的属性和方法与父类的私有属性和方法同名时,父类的私有属性和方法不会被覆盖。

B类():

# _ _宣布私有化

__name='张三'

def __init__(self):

自我。_ _年龄=23岁

自我。__luange='python '

def __method(自我):

#私有方法

Print('我叫{},今年{}岁,我喜欢{}。'。格式(自我。__name,self。_ _年龄,自我。_ _栾格))

定义乐趣(自我):

#公共方法

打印(“这是一个公共方法”)

丙类(乙类):

__name='李四'

def __init__(self):

超级()。__init__()

自我。_ _年龄=24岁

自我。__luange='C '

def fun1(自身):

#访问父类b的私有属性和私有方法。

打印(自我。__name,self。_ _年龄,自我。_ _栾格)

自我。_ _方法()

def __method(自我):

# C类的私有方法,与父方法同名,但不重写父方法

Print('我叫{},今年{}岁,我喜欢{}。'。格式(自我。__name,self。_ _年龄,自我。_ _栾格))

#调用父类的私有方法

b()。_ B _ _方法()

if __name__=='__main__ ':

c=C()

#访问c类的私有方法。

c._ C _ _方法()

结果如下:

我叫李四,今年24岁,喜欢c。

我的名字叫张三。我今年23岁。我喜欢python。

可以看到,子类C并没有覆盖父类b的__method()方法,这是为什么呢?让我们打印B和C的目录,如下:

['_B__age ',' _B__luange ',' _C__age ',' _C__luange ',' fun1 ',

' C _ method ',' _doc__ ',' _ B _ name ',' _ B _ method ',' _ C _ name ',]

可以看到,在C类的dir中,父类B的私有属性和方法以_B__ attributes (methods)的形式存在,而II类C的私有属性和方法以_C__ attributes (methods)的形式存在,即类的私有属性和方法会以_ class name _ attributes (methods)的形式存在于dir中,所以当子类的属性和方法与父类的属性和方法私有时,

三 访问及修改类的私有属性和私有方法

通过私有化属性和方法,类可以保护它们。但是当外部需要被访问和改变时会发生什么呢?就像电视机一样,电脑也是对外提供固定接口的。

以上,虽然我们可以以类名()的形式访问一个类的私有属性和私有方法。_ class name _ _ attribute(实例属性)或类名。_ class name _ _ attribute (class属性),这是违背编程规范的,也是不支持的,就像它不会打开电视机来操作一样。

正确对类的私有属性和私有方法进行访问修改的一般有两种发方法,如下:

1. 自定义公有方法

D类():

__name='张三'

def __init__(self):

自我。_ _年龄=23岁

自我。__luange='python '

def __method(自我):

Print('我叫{},今年{}岁,我喜欢{}。'。格式(自我。__name,self。_ _年龄,自我。_ _栾格))

定义获取值(自身):

回归自我。__name,self。_ _年龄,自我。_ _栾格

def get_method(self):

自我。_ _方法()

def set_value(自我,姓名,年龄,乱格):

自我。__name,self。_ _年龄,自我。__luange=姓名、年龄、luange

if __name__=='__main__ ':

d=D()

#通过get_value方法访问私有属性

print(d.get_value())

#通过get_method方法访问私有方法

打印('=' * 30)

get_method()

#通过set_value方法修改私有属性

打印('='*30)

print(d.get_value())

D.set_value(《王子》,25,《Linux》)

print(d.get_value())

get_method()

输出结果:

(《张三》,23,“蟒蛇”)

==============================

我的名字叫张三。我今年23岁。我喜欢python。

==============================

(《张三》,23,“蟒蛇”)

(《王子》,25,《Linux》)

我叫王二麻子,今年25岁,喜欢Linux。

如你所见,我们可以通过自定义get_value()、get_method()和set_value()方法来访问和修改私有属性和私有方法。

2. property

property一般有两个作用,如下:

作为装饰者,@property将类的方法变成只读的类属性。属性重新实现属性的getter和setter方法。

来看看下面这个E类,如下:

E类():

__name='张三'

def __init__(self):

自我。_ _年龄=23岁

自我。__luange='python '

def __method(自我):

Print('我叫{},今年{}岁,我喜欢{}。'。格式(自我。__name,self。_ _年龄,自我。_ _栾格))

定义获取值(自身):

回归自我。_ _名称

定义集合值(自身,名称):

自我。__name=name

getValue=property(获取值,设置值)

@属性

def get_method(self):

自我。_ _方法()

if __name__=='__main__ ':

e=E()

#访问

打印(电子获取价值)

获取方法

#修改

E.getValue='王2 '

打印(电子获取价值)

结果:

张三

我的名字叫张三。我今年23岁。我喜欢python。

王二

正如您所看到的,在我们将get_value和set_value方法传递到属性中之后,类方法被转换为类属性并被赋给getValue变量。此时e.getValue为只读,即get_value方法,e. value='王二'为修改,即get_value方法。类似地,通过@propert,get_method方法变成了一个属性。

下面的属性重新实现了一个属性的getter和setter方法,它不同于上面的方法,比上面的方法更常用。

E类():

__name='张三'

def __init__(self):

自我。_ _年龄=23岁

自我。__luange='python '

def __method(自我):

Print('我叫{},今年{}岁,我喜欢{}。'。格式(自我。__name,self。_ _年龄,自我。_ _栾格))

@属性

定义名称(自身):

回归自我。_ _名称

@name.setter

定义名称(自己,名称):

自我。__name=name

if __name__=='__main__ ':

e=E()

#访问

打印(e.name)

#修改

打印('修改前:',e.name)

隔壁的老王

打印('已修改:',e.name)

输出结果:

张三

修改前:张三

改装后:隔壁老王

上面,name方法首先被发送给propert decorator进行修饰,然后调用修饰后的setter方法修改private属性。

关于Python面向对象打包细节的这篇文章就到这里了。有关Python打包的更多信息,请搜索我们以前的文章或继续浏览下面的相关文章。希望你以后能支持我们!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: