python 3 封装

python 3 封装

从封装本身的意思去理解,封装就好像是拿来一个麻袋,把小鱼,小虾,小王八,一起装进麻袋,然后把麻袋封上口子。照这种逻辑看,封装=‘隐藏’,这种理解是相当片面的。

先看如何隐藏

在python中用双下划线开头的方式将属性隐藏起来(设置成私有的)

其实这仅仅这是一种变形操作

类中所有双下划线开头的名称如__x都会自动变形成:_类名__x的形式:

class A:

    __N=0 #类的数据属性就应该是共享的,但是语法上是可以把类的数据属性设置成私有的如__N,会变形为_A__N

    def __init__(self):

        self.__X=10 #变形为self._A__X

    def __foo(self): #变形为_A__foo

        print(‘from A‘)

    def bar(self):

        self.__foo() #只有在类内部才可以通过__foo的形式访问到.

A._A__N是可以访问到的,即这种操作并不是严格意义上的限制外部访问,仅仅只是一种语法意义上的变形。

这种自动变形的特点:

  1. 类种定义的__x只能在内部使用,如self.__x,引用的就是变形的结果。
  2. 这种变形其实正是针对外部的变形,在外部是无法通过__x这个名字访问到的。
  3. 在子类定义的__x不会覆盖在父类定义的__x,因为子类中变形成了:_子类名__x,而父类中变形成了:_父类名__x,即双下划线开头的属性在继承给子类时,子类是无法覆盖的。
  • 对于这一层面的封装(隐藏),我们需要在类中定义一个函数(接口函数)在它内部访问被隐藏的属性,然后外部就可以使用了

这种变形需要注意的问题是:

1.这种机制也没有真正意义上限制我们从外部直接访问属性,知道了雷鸣和属性名就可以拼出名字:_类名__属性,然后皆可以访问了,如a._A__N

2.变形的过程只在类的定义时放生一次,在定义后的赋值操作,不会变形

3.在继承中,父类如果不想让子类渡改自己的方法,可以将方法定义为私有的

python并不会真的阻止你访问私有的属性,模块也遵循这种约定,如果模块名以单下划线开头,那么from module import *时不能被导入,但是你from module import _private_module依然是可以导入的其实很多时候你去调用一个模块的功能时会遇到单下划线开头的(socket._socket,sys._home,sys._clear_type_cache),这些都是私有的,原则上是供内部调用的。作为外部也可以用,只过写出代码比较傻了,python要想与其他编程语言一样,严格控制属性的访问权限,只能借助内置方法如__getattr__

#先看如何隐藏

class Foo:

    __N=111111 #_Foo__N

    def __init__(self,name):

        self.__Name=name #self._Foo__Name=name

    def __f1(self): #_Foo__f1

        print(‘f1‘)

    def f2(self):

        self.__f1() #self._Foo__f1()

f=Foo(‘egon‘)

# print(f.__N)

# f.__f1()

# f.__Name

f.f2() #通f

#这种隐藏需要注意的问题:

#1:这种隐藏只是一种语法上变形操作,并不会将属性真正隐藏起来

print(Foo.__dict__)

print(f.__dict__)

print(f._Foo__Name)

print(f._Foo__N)

#2:这种语法级别的变形,是在类定义阶段发生的,并且只在类定义阶段发生

Foo.__x=123123123123123123123123123123123123123123

print(Foo.__dict__)

print(Foo.__x)

f.__x=123123123

print(f.__dict__)

print(f.__x)

#3:在子类定义的__x不会覆盖在父类定义的__x,因为子类中变形成了:_子类名__x,而父类中变形成了:_父类名__x,即双下滑线开头的属性在继承给子类时,子类是无法覆盖的。

class Foo:

    def __f1(self): #_Foo__f1

        print(‘Foo.f1‘)

    def f2(self):

        self.__f1() #self._Foo_f1

class Bar(Foo):

    def __f1(self): #_Bar__f1

        print(‘Bar.f1‘)

b=Bar()

b.f2()

#封装不是单纯意义的隐藏

#1:封装数据属性:将属性隐藏起来,然后对外提供访问属性的接口,关键是我们在接口内定制一些控制逻辑从而严格控制使用对数据属性的使用

class People:

    def __init__(self,name,age):

        if not isinstance(name,str):

            raise TypeError(‘%s must be str‘ %name)

        if not isinstance(age,int):

            raise TypeError(‘%s must be int‘ %age)

        self.__Name=name

        self.__Age=age

    def tell_info(self):

        print(‘<名字:%s 年龄:%s>‘ %(self.__Name,self.__Age))

    def set_info(self,x,y):

        if not isinstance(x,str):

            raise TypeError(‘%s must be str‘ %x)

        if not isinstance(y,int):

            raise TypeError(‘%s must be int‘ %y)

        self.__Name=x

        self.__Age=y

p=People(‘egon‘,18)

p.tell_info()

# p.set_info(‘Egon‘,‘19‘)

p.set_info(‘Egon‘,19)

p.tell_info()

#2:封装函数属性:为了隔离复杂度

#取款是功能,而这个功能有很多功能组成:插卡、密码认证、输入金额、打印账单、取钱

#对使用者来说,只需要知道取款这个功能即可,其余功能我们都可以隐藏起来,很明显这么做

#隔离了复杂度,同时也提升了安全性

class ATM:

    def __card(self):

        print(‘插卡‘)

    def __auth(self):

        print(‘用户认证‘)

    def __input(self):

        print(‘输入取款金额‘)

    def __print_bill(self):

        print(‘打印账单‘)

    def __take_money(self):

        print(‘取款‘)

    def withdraw(self):

        self.__card()

        self.__auth()

        self.__input()

        self.__print_bill()

        self.__take_money()

a=ATM()

a.withdraw()
# _x=123

示例代码

时间: 2024-12-31 18:09:34

python 3 封装的相关文章

将Python脚本封装成exe可执行文件 转

将Python脚本封装成exe可执行文件 http://www.cnblogs.com/renzo/archive/2012/01/01/2309260.html cx_freeze是用来将 Python 脚本封装成可执行程序的工具,支持最新的Python3.2版本.生成的执行文件具有跨平台性,而且运行的系统无须安装Python.目前类似功能的工具还有py2exe 和 PyInstaller,其中貌似py2exe知名度最高了,但是很久没有更新了,至于打包质量不做评价,毕竟萝卜青菜各有所爱:PyI

python之--------封装

一.封装: 什么是封装呢?(封装不是单纯意义的隐藏,其实它还是可以查看的) 就是把一些不想让别人看的给隐藏起来了 封装数据:目的是保护隐私 功能封装:目的是隔离复杂度 如果用了私有的,在类的外部,无法直接使用变形的属性,但是在类的内部可以直接使用 1 1.用我们常用的__init__方法里的self取值 2 class Course:#恰好给我们提供了实现这种思路的方法 3 # #一种思路,python 4 def __init__(self,price,period,name): 5 self

Python基础-封装与扩展、静态方法和类方法

一.封装与扩展 封装在于明确区分内外,使得类实现者可以修改封装内的东西而不影响外部调用者的代码:而外部使用者只知道一个接口(函数),只要接口(函数)名.参数不变,使用者的代码永远无需改变.这就提供一个良好的合作基础--或者说,只要接口这个基础约定不变,则代码改变不足为虑. 实例: 1 #类的设计者 2 class Room: 3 def __init__(self,name,owner,width,length,high): 4 self.name=name 5 self.owner=owner

python基础----封装

从封装本身的意思去理解,封装就好像是拿来一个麻袋,把小猫,小狗,小王八,还有egon和alex一起装进麻袋,然后把麻袋封上口子.但其实这种理解相当片面 首先我们要了解 要封装什么 你钱包的有多少钱(数据的封装) 你的性取向(数据的封装) 你撒尿的具体功能是怎么实现的(方法的封装) 为什么要封装 封装数据的主要原因是:保护隐私(作为男人的你,脸上就写着:我喜欢男人,你害怕么?) 封装方法的主要原因是:隔离复杂度(快门就是傻瓜相机为傻瓜们提供的方法,该方法将内部复杂的照相功能都隐藏起来了,比如你不必

python的封装与解构

封装 将多个值使用逗号分割,组合在一起 本质上,返回一个元祖,只是省掉了小括号 python特有语法,被很多语言学习和借鉴 t1 = (1,2) #定义为元祖 t2 = 1,2 #将1和2封装成元祖 print(type(t1)) print(type(t2)) 返回类型都为元组: <class 'tuple'> <class 'tuple'> 使用方法: a = 4 b = 5 temp = a a = b b = temp # 等价于 a,b = b,a #等号右边使用了封装,

Python的封装、继承和多态

数据封装.继承和多态是面向对象的三大特点. 数据封装: 在某个类中,比如Student类(初始化又name和score两个属性),每个实例都拥有各自的name,score这些数据.我们可以通过函数来访问这些数据,比如打印一个学生的成绩.直接定义一个输出函数,输出name和对应的score即可. 但是,既然student实例本身就有这些数据,要访问这些数据,就没有必要从外面的函数去访问,可以直接在Student类的内部定义访问数据的函数,这样,就把"数据"给封装起来了,这些封装数据的函数

python 属性封装

120 1 #封装 2 3 class Person: 4 def __init__(self,name,passwd): 5 self.name=name 6 self.__passwd=passwd 7 8 def get_pwd(self): 9 return self.__passwd 10 11 Jack=Person("Jack","abc123") 12 13 print(Jack._Person__passwd) 14 print(Jack.get_

python文件封装成可执行exe文件

最近写了一个小小的程序,需要进行封装exe,下面就给大家介绍一下如何用pyinstaller去封装程序为exe程序. 首先,需要安装一下pip这个应用,这个已经在前面的文章中说过了,windows和linux都有请借鉴windows和linux. 第二步,安装好pip之后,在cmd命令窗口中输入pip install pyinstaller即能安装上pyinstaller,那么接下来要介绍一下关于pyinstaller几个指令了:-w指令直接发布的exe应用带命令行调试窗口,在指令内加入-w命令

Python面向对象封装案例

01. 封装 封装 是面向对象编程的一大特点 面向对象编程的 第一步 —— 将 属性 和 方法 封装 到一个抽象的 类 中 外界 使用 类 创建 对象,然后 让对象调用方法 对象方法的细节 都被 封装 在 类的内部 02. 小明爱跑步 需求 小明 体重 75.0 公斤 小明每次 跑步 会减肥 0.5 公斤 小明每次 吃东西 体重增加 1 公斤 注意: 在 对象的方法内部,是可以 直接访问对象的属性 的! class Person: def __init__(self,name,weight):