广告
返回顶部
首页 > 资讯 > 后端开发 > Python >封装,封装的原理,Property ,s
  • 123
分享到

封装,封装的原理,Property ,s

原理Property 2023-01-31 00:01:55 123人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

1,封装 ## 什么是封装 what 对外隐藏内部的属性,以及实现细节,并给外部提供使用的接口 学习封装的目的:就是为了能够限制外界对内部数据的方法 注意 :封装有隐藏的意思,但不是单纯的隐藏 python 中属性的权限分为两种:

1,封装

## 什么是封装 what 

对外隐藏内部的属性,以及实现细节,并给外部提供使用的接口
学习封装的目的:就是为了能够限制外界对内部数据的方法
注意 :封装有隐藏的意思,但不是单纯的隐藏

python 中属性的权限分为两种:  
  1,分开的
    没有任何限制,谁都可以访问
  2,私有的
    只有当前类本身能够访问
  默认为公共的

##如何封装 how 

为什么要封装:

  1,提高安全性  (封装属性)
       
  2,隔离复杂度  (封装方法)

    
一个类中分为两种数据,属性和方法:
封装属性:

class Student: def __init__(self,name,age,gender,id_card): self.name = name self.age = age self.gender = gender self.__id_card = id_card def show_id_card(self): # 可以在这里添加额外的任何逻辑代码 来限制外部的访问 #在类的内部 可以访问 print(self.__id_card)

对私有属性的访问以及修改:

class Student: def __init__(self,name,age,gender,id_card): self.name = name self.age = age self.gender = gender self.__id_card = id_card #访问器 def get_id_card(self,pwd): #可以在这里添加额外的任何逻辑代码,来限制外部的访问 #在类的内部,可以访问 if pwd == '123': return self.__id_card raise Exception('密码错误!') #修改被封装的属性,称之为设置器 def set_id_card(self,new_id): #身份证必须是字符串类型 #长度必须是18位 if isinstance(new_id,str) and len(new_id) == 18: self.__id_card = new_id else: raise Exception('身份证号码必须是字符串,且长度为18') s = Student('rose',10,'man','111111111111111111') print(s.get_id_card('123')) #111111111111111111 #设置属性 s.set_id_card('222222222222222222') print(s.get_id_card('123')) #222222222222222222

 

什么样的方法应该被封装起来 :
  当这个对象存在一个机密性的属性 例如 人的身份证 银行卡密码等等,这样属性不应该被外界直接 访问当 ,那就封装起来。
​ 一个为内部提供支持的方法,不应该让外界直接访问,那就封装起来 ,如下例中的 user_auth等...
class ATM: #提供给外部访问的一个接口 def withdraw(self): #输入账号和密码 self.__user_auth() #输入取款金额 self.__input_money() #保存记录 self.__save_record() #封装内部的实现细节 def __user_auth(self): print('输入账号和密码') def __input_money(self): print('输入取款金额') def __save_record(self): print('记录流水') a = ATM() a.withdraw()

  #输入账号和密码
  #输入取款金额
  #记录流水

 

 

2,封装的原理:


''' Python 是通过变形的方式来实现的封装 如何变形 : 在名称带有双下划线开头的变量名字前添加_类名 如:_Person_id_card 当然通过变形后的名字可以直接访问被隐藏的属性 ,但通常不这样做 如: p._Person__id_card 变形仅在类的定义阶段发生一次,后续再添加在带有双下划线的任何属性都不会变形,就是普通函数 ''''' class Person: def __init__(self,name,age,id_card): self.name = name self.age = age self.__id_card = id_card #_Person__id_card def get_id_card(self): return self.__id_card p = Person('rose',20,'12321323123123') print(p.__dict__) #{'name': 'rose', 'age': 20, '_Person__id_card': '12321323123123'} print(p.name) p.__id_card = '123' #重新开辟了一块空间存储 print(p.__dict__) #{'name': 'rose', 'age': 20, '_Person__id_card': '12321323123123', '__id_card': '123'} print(p._Person__id_card) #直接强制访问 12321323123123 p.__gender = 'man' print(p.__dict__) #{'name': 'rose', 'age': 20, '_Person__id_card': '12321323123123', '__id_card': '123', '__gender': 'man'}


3,Property ,setter ,deleter


Property 作用 : 将一个方法伪装成普通属性 为什么用 property : 希望将访问私有属性和普通属性的方式变得一致 与property相关的两个装饰器:   setter : 用点语法 给属性赋值时触发   deleter: 用点语法删除属性时触发 class Teacher: def __init__(self,name,age,salary): self.name = name self.age = age self.__salary = salary @property   #getter 用于访问私有属性的值,也可以访问普通属性 def salary(self): return self.__salary @salary.setter #用于设置私有属性的值,也可以设置普通属性 def salary(self,new_salary): self.__salary = new_salary @salary.deleter #用于设置私有属性的,也可以删除普通属性 def salary(self): print(self.__dict__) #{'name': 'owen', 'age': 29, '_Teacher__salary': 88888} del self.__dict__['_Teacher__salary'] t = Teacher('owen',29,88888) # del t.salary print(t.salary) #88888 t.salary = 100000 print(t.salary) #100000 ''' 总结: 被封装的属性在访问时,需要调用方法,而普通属性直接点就OK,这样一来对于对象的使用者而言 必须知道要访问的属性,是私有还是公开,然后在调用对应的方法.用起来就会比较麻烦 此时,我们的目的就是让访问私有属性和访问普通属性的方式一样通过点来调用   property装饰器:就是用来将一个方法伪装成属性,可以直接通过点来调用 '''

 

'''
property的另一种使用场景,计算属性

什么是计算属性:
    一个属性它的值不是固定死的,而是通过计算产生的

'''''

class Person: def __init__(self,name,height,weight): self.name = name self.height = height self.weight = weight # self.BMI = weight /(height**2) @property def BMI(self): return self.weight/(self.height**2) @BMI.setter def BMI(self,new_BMI): print('BMI 不支持自定义.....') p = Person('owen',1.78,60) print(p.BMI) #18.93700290367378 p.weight = 90 print(p.BMI) #28.40550435551067 #被封装的内容(私有的) 不可以被继承 class A: __name = 'rose' #变形后 _A__name def __say_hi(self): print('A say hi') class B(A): def test(self): # print(super().__name) #变形后 _B__name 在哪个类就以哪个类变形 print(A._A__name) #通过super()不能使用父类的私有属性,可以通过类名直接访问 b = B() b.test()

 

4,多态

"""
多态 :
多态不是一个具体的技术  或代码
指的是 多个不同类型对象 可以响应同一个方法 ,产生不同结果

某种事物具备多个不同形态
例如 水:   气态  固态  液态
     动物: 人  猫  猪
     汽车人:  汽车 飞机  人型

OOP中 标准解释: 多个不同类型对象 可以响应同一个方法  并且产生不同结果

多态的带来的好处:
    只需要学习基类中的使用方法即可, 不需要关心具体的哪一个类 以及实现的,以不变应万变 ,提高了灵活性
    提高扩展性


如何实现多态:
    鸭子类型 就是典型的多态 多种不同类型 使用方法一样

"""

# import abc
# class Animal(metaclass=abc.ABCMeta):
# 
#     @abc.abstractmethod
#     def bark(self):
#         pass
# 
#     @abc.abstractmethod
#     def run(self):
#         pass
# 
#     @abc.abstractmethod
#     def sleep(self):
#         pass



class Person():

    def bark(self):
        print("Hello!")

    def run(self):
        print("两条腿跑!")

    def sleep(self):
        print("躺着睡!")


class Cat():

    def bark(self):
        print("喵喵喵")

    def run(self):
        print("四条腿跑!")

    def sleep(self):
        print("趴着睡!")

class Pig():
    def bark(self):
        print("哼哼哼!")

    def run(self):
        print("四条腿跑!")

    def sleep(self):
        print("侧躺着睡!")


person1 = Person()
cat1 = Cat()
pig1 = Pig()

person1.sleep()
cat1.sleep()
pig1.sleep()

# 如果没有多态  需要分别学习 person  cat pig 的不同使用方法 这对于使用者而言太麻烦了


# 一个用来管理动物的方法   只要你传入是一个动物 我就按照动物的标准来使用 完全不用考虑你具体是什么类型
def management_animal(animal): print("==================正在溜%s=============" % animal.__class__.__name__) animal.bark() animal.run() animal.sleep() # 来了一堆动物 person1 = Person() cat1 = Cat() pig1 = Pig() management_animal(person1) management_animal(cat1) management_animal(pig1)
class Dog(): def bark(self): print("汪汪汪...") def run(self): print("四条腿跑!") def sleep(self): print("趴着睡!") dog1 = Dog() management_animal(dog1) class Fish(): def bark(self): print("超声波...") def run(self): print("游来游去.....") def sleep(self): print("睁眼睡觉....") f = Fish() management_animal(f) # 无处不在的多态 # def MY_LEN(obj): # return obj.__len__() # # print(MY_LEN("abcdefg")) # print(MY_LEN([1,2,3,4])) # print(MY_LEN({"name":123})) print(len("1231212121"))

 

5,常用的内置函数 ,__str__ , __del__

__str__ :

''' 类中的__str__: 该方法在object中有定义,默认行为,返回对象类型以及地址 在将对象转为字符串时执行 注意:返回值必须为字符串类型 子类可以覆盖该方法来完成,对打印内容的自定义 '''''

class Person: def __init__(self,name,age): self.name = name self.age = age #将对象转换为字符串时执行 def __str__(self): print('str run') return 'my name is %s.age is %s'%(self.name,self.age) p = Person('rose',20) '''#在打印前都会先将要打印的内容转为字符串,通过调用__str__函数''' print(p) #my name is rose.age is 20 str(p) #str run

 

'''
__del__:
当对象被删除前会自动调用该方法 声明的时候会删除对象? 1,程序运行结束,解释器退出,将自动删除所有数据 2,手动调用del 时也会删除对象 注意: 该函数不是用来删除对象的 使用场景: 当你的对象在创建时,开启了不属于解释器的资源 ,例如: 打开了一个文件 必须保证当前对象被删除时,同时关闭额外的资源,如:文件 也称之为析构函数(一个个拆分,解析) 构造 的反义词 构造:指的是从无到有 析构:指的是有到无 简单的说就对象所有数据全部删除 总结:__del__该函数 用于在对象删除前做的一些清理操作(或提醒)
''''' #假设要求每一个person对象都要绑定一个文件 class Person: def __init__(self,name,path): self.name = name self.file = open(path,encoding='utf-8') #读取数据的方法 def read_data(self): return self.file.read() def __del__(self): print('del run1') #当程序执行完后才会执行这个 self.file.close() p = Person('owen','封装方法.py') print(p.read_data())

 

6,反射

英文中叫反省 (自省)   

面向对象中的反省 指的是,一个对象必须具备,发现自身属性,以及修改自身属性的能力;   

一个对象在设计初期,可能考虑不够周全后期需要删除或修改已经存在的属性, 和增加属性 

## 反射就是通过字符串来操作对象属性

涉及到的方法:
hasattr   判断是否存在某个属性 getattr 获取某个属性的值 setattr 新增或修改某个属性 delattr   删除某个属性 案例1:
import os class Student: def __init__(self,name): self.name = name def www(self): print('123') stu = Student('rose') #反射的四个方法 print(hasattr(stu,'name')) #True print(getattr(stu,'name')) #rose setattr(stu,'name','123') print(getattr(stu,'name')) #123 delattr(stu,'name') print(hasattr(stu,'name')) #False

print(hasattr(stu,'www')) #True
案例2:
class MY_CMD: def dir(self): os.system('dir') def ipconfig(self): os.system('ipconfig') cmd = MY_CMD() while True: name = input('请输入要执行的指令:') if hasattr(cmd,name): method = getattr(cmd,name) print(method) #绑定方法: <bound method MY_CMD.dir of <__main__.MY_CMD object at 0x0000021FFF8765F8>> method() else: print('sorry this method is not exists....!')

  

7,动态导入模块:

'''
直接写import 称之为静态导入,建立在一个基础时,提前已经知道有这个模块

动态导入:指的是在需要的任何时候,通过指定字符类型,包名称来导入需要的模块

import importlib
mk = importlib.import_module(m_name)
mk 即导入成功的模块
'''''


#动态导入模块.py

import importlib

m_name = input('请输入要导入的模块名称:').strip()
mk = importlib.import_module(m_name)
print(mk)       #<module '计算属性' from 'D:\\Python_Project\\ClassRoom\\day26\\练习\\计算属性.py'>

from day26.练习.build_house import conf
print(conf)

#build_house/conf.py decoration = [ 'build_house.my_decoration.Table', 'build_house.my_decoration.Light', 'build_house.my_decoration.Bed', 'other_decoration.Sofa' ] #build_house/core.py import importlib from day26.练习.build_house import conf def building(): print('毛坯房建造完成.....') #读取用户提供配置信息,来加载用户所需要的一系列装饰品 for cls_info in conf.decoration: # print(cls_info) #切割类名和模块路径 m_name,cls_name = cls_info.rsplit('.',1) # print(m_name,cls_name) #build_house.my_decoration Table #导入模块 mk = importlib.import_module(m_name) print(mk) #从模块中获取类 if not hasattr(mk,cls_name): continue cls = getattr(mk,cls_name) obj = cls() print(obj) building() #build_house/my_decoration.py class Table: pass class Light: pass class Bed: pass

 

--结束END--

本文标题: 封装,封装的原理,Property ,s

本文链接: https://www.lsjlt.com/news/182339.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 封装,封装的原理,Property ,s
    1,封装 ## 什么是封装 what 对外隐藏内部的属性,以及实现细节,并给外部提供使用的接口 学习封装的目的:就是为了能够限制外界对内部数据的方法 注意 :封装有隐藏的意思,但不是单纯的隐藏 python 中属性的权限分为两种:...
    99+
    2023-01-31
    原理 Property
  • JS中bridge的原理与封装
    目录一、hybird背景介绍1、借助原生可以实现以下能力二、 我们可以看一下纯H5和 app应用之间的区别三、JsBridge 原理以及实现方式1、 JavaScript调用Nati...
    99+
    2022-11-13
  • java封装类是如何封装的
    在Java中,封装是一种面向对象编程的概念,用于隐藏内部实现细节,并通过公共方法提供对数据的访问和操作。封装类是为了封装基本数据类型...
    99+
    2023-10-23
    java
  • mybatis自动封装的原理是什么
    MyBatis的自动封装是通过使用Java的反射机制来实现的。 MyBatis在执行查询操作时,会通过Java的反射机制,根据查询结...
    99+
    2023-10-27
    mybatis
  • 深入浅析JAVA中封装的原理
    本篇文章为大家展示了深入浅析JAVA中封装的原理,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。第一节 什么是JAVA中的封装面向对象的三大特性:封装、继承、多态。概念:将类的某些信息隐藏在类的内部,...
    99+
    2023-05-31
    java 封装 ava
  • Apicloud 之 Android studio 原生封装
    19年年底离职,回家过年之前,尝试性投递了几家公司,面试机会蛮多的,就选了两家近的去看看,第一家面试就通过了,安心的回家,迎接新年新气象----...
    99+
    2022-06-06
    Android Studio studio 封装 apicloud Android
  • js原生Ajax如何封装
    这篇文章主要介绍了js原生Ajax如何封装,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。原理及概念AJAX即“Asynchronous Ja...
    99+
    2022-10-19
  • python3--面向对象的三大特性:封装,property,classmethod,staticmethod
    python中的封装隐藏对象的属性和实现细节,仅对外提供公共访问方式好处:1 将变化隔离2 便于使用3 提供复用性4 提高安全性封装原则1 将不需要对外提供的内容都隐藏起来2 把属性都隐藏,提供公共方法对其访问私有变量和私有方法在pytho...
    99+
    2023-01-30
    三大 面向对象 特性
  • C++封装详解——从原理到实践
    C++封装详解——从原理到实践 引言1.1 什么是封装1.2 为什么使用封装 封装原理2.1. 类和对象2.2 C++类成员的访问权限以及类的封装访问权限控制继承权限公有继承保护继承私有继...
    99+
    2023-10-21
    c++ 开发语言 linux 服务器 qt
  • android控件封装 自己封装的dialog控件
    自定义dialog肯定是用的很多了但是感觉每次做都是很乱 单纯完成任务而已,现在封装了一下 以后用到直接copy 先上图: 主activity 代码如下: package c...
    99+
    2022-06-06
    封装 dialog Android
  • 原生AJAX封装的实现方法
    这篇文章主要介绍“原生AJAX封装的实现方法”,在日常操作中,相信很多人在原生AJAX封装的实现方法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”原生AJAX封装的实现方法”...
    99+
    2022-10-19
  • JavaScript要封装的原因是什么
    这篇文章主要介绍“JavaScript要封装的原因是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“JavaScript要封装的原因是什么”文章能帮助大家解决问题...
    99+
    2022-10-19
  • PHP中封装性的设计原则
    封装性是面向对象编程的重要原则之一,它主要用于隐藏对象的内部实现细节,只暴露出必要的接口供外部访问。封装性的设计可以提高代码的复用性、可维护性和安全性。在PHP中,我们可以使用类和访问修饰符来实现封装性的设计。封装数据成员在PHP中,我们可...
    99+
    2023-10-21
    设计 PHP 封装原则
  • Python 类的封装
    封装(Encapsulation)是对 object 的一种抽象,即将某些部分隐藏起来,在程序外部看不到,即无法调用(不是人用眼睛看不到那个代码,除非用某种加密或者混淆方法,造成现实上的困难,但这不是封装)。要了解封装,离不开“私有化”,就...
    99+
    2023-01-31
    Python
  • JS中bridge的原理与封装实例分析
    本篇内容主要讲解“JS中bridge的原理与封装实例分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“JS中bridge的原理与封装实例分析”吧!一、hybird背景介绍一般原生app发版周期长...
    99+
    2023-07-02
  • epoll封装reactor原理剖析示例详解
    目录reactor是什么?reactor模型三个重要组件与流程分析组件流程将epoll封装成reactor事件驱动封装每一个连接sockfd变成ntyevent封装epfd和ntye...
    99+
    2022-11-13
  • H5封装是什么意思,H5封装的APP与原生的有什么区别
    一、H5封装是什么 H5封装通常指的是在前端开发中,对HTML5(H5)技术进行封装和抽象,以简化代码复用和功能调用的过程。HTML5是一种标准的超文本标记语言,用于构建和展示网页内容,而H5封装是在此基础上对常用的功能、组件...
    99+
    2023-10-29
    有什么区别 APP
  • Node Mysql事务处理封装
    node回调函数的方式使得数据库事务貌似并没有像java、php那样编写简单,网上找了一些事务处理的封装并没有达到自己预期的那样简单编写,还是自己封装一个吧。封装的大体思路很简单:函数接受一个事务处理的函数...
    99+
    2022-10-18
  • 原生js怎么实现对Ajax的封装
    这篇文章主要介绍原生js怎么实现对Ajax的封装,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!前言众所周知,jquery在我们日常开发中的使用频率非常高,与js相比,我们省去了冗长的...
    99+
    2022-10-19
  • 将原生JDBC封装实现CRUD的案例
    将原生JDBC封装实现CRUD 1、项目结构 pom.xml加入依赖 2、思路 初步 1、加载数据库驱动连接数据库 2、sql语句 3、创建PreparedStatement对象...
    99+
    2022-11-12
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作