首页 > 第二十五章 面向对象------封装、内置函数、反射、动态导入

第二十五章 面向对象------封装、内置函数、反射、动态导入

1、封装

什么是封装?

  1.对外部隐藏内部的属性,以及实现细节,给外部提供使用的接口

    注意:封装有隐藏的意思,但不是单纯的隐藏

    学习封装的目的:就是为了能够限制外界对内部数据的访问

  python中属性的权限分为两种:

  1.公开的

    没有任何限制,谁都可以访问

  2.私有的

    只有当前类本身能狗访问

  默认为公共的

为什么要封装?

  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_crad(self,new_id):

 身份证必须是字符串类型

 长度必须是18位

if isinstance(new_id,str) and len(new_id) == 18:

self.__id_card = new_id

else:

raise Exception("身份证号码 必须是字符串 且长度必须为18!")

什么样的方法应该被封装起来?

  一个为内部提供支持的方法,不应该让外界直接访问,那就封装起来,如下例中的  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('余额为1000000000,请输入取款金额!')

  def __save_record(self):

    print('记录流水......')

封装原理:

python是通过 变形的方式来实现的封装

如何变形 在名称带有双下划线开头的变量名字前添加_类名 如_Person__id_card

当然通过变形后的名字可以直接访问被隐藏的属性 但通过不应该这么做

变形仅在类的定义阶段发生一次 后续再添加的带有双下划线的任何属性都不会变形 就是普通属性

什么时候用?

封装属性:

  当这个对象存在一个机密性的属性,例:身份证信息,银行卡密码等,这样属性不应该被外界直接访问到时就将其封装。

封装方法:

  一个为内部提供支持的方法,不应该让外界直接访问,那就将其封装。

 

Prorety

作用:将一个方法伪装成普通属性;用property是为了希望将访问私有属性和普通属性的方式变得一致。

与Prorety相关的两个装饰器:

setter:用 . (点)语法给属性赋值是触发

deleter:用 . (点)语法删除属性时触发

例:

calss 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):

    self.__salary=new_salary

  @salary.deleter   # 用来设置私有属性的值  也可以删除普通属性

    # print("can not delete salary!")

    del  self.__dict__['Teacher__salary']

Property 计算属性使用场景:

什么是计算属性:

  一个属性它的值不是固定死的,而是通过计算动态产生的。

class Person:

  def __inin__(self,name,height,weight):

    self.name=name

    self.height=height

    self.weight=weight

  @aproperty

  def  BMI(self):

     return sdlf.weight/(self.height**2)

  @setter

  def  BMI(self,new_BMI):

    print('BMI 不支持自定义......')

p=person('egon',1.7,80)

print(p.BMI)

P.BMI=10

 

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

使用多态的好处:

  只需要学习积累中的使用方法即可,不需要关心具体的哪一个类,实现  

   以不变应万变  提高灵活性  提高扩展性

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

  鸭子类型:就是典型的多态,多重不同类型 使用方法一样

案例:

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("侧躺着睡!")

# 一个用来管理动物的方法 只要你传入是一个动物 我就按照动物的标准来使用 完全不用考虑你具体是什么类型

def management_animal(animal):

  print("==================正在溜%s=============" % animal.__class__.__name__)

animal.bark()

animal.run()

animal.sleep()

 

常用的内置函数

__str__

对象转成字符串是被强制执行

__del__

__del__:当对象被删除前会自动调用 ,该方法声明时候会删除对象?

    1.程序运行结束,解释器退出,将自动删除所有数据

    2.手动调用del 时也会删除对象

    注意:该函数不是用来删除对象的

使用场景:

  当你的对象在创建时,开启了不属于解释器的资源,例如打开一个文件必须保证对象被删除时,

同时关闭额外的资源,如文件。

__del__也称之为析构函数,析构,构造的反义词

  构造:值得是从无到有

  析构:至从有到无

  简单的说就对象所有数据全部删除

总结:__del__该函数,用于在对象删除前做一些清理操作

class Person:

  def __init__(self,name,path,mode="rt",encoding="utf-8"):

    self.name = name

    self.file = open(path,mode,encoding=encoding)

 

# 读取数据的方法

def read_data(self):

  return self.file.read()



def __del__(self):

  print("del run!")

  self.file.close()

 

反射(英文中叫反省,自省)

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

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

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

涉及到方法:

hasattr 判断是否存在某个属性

getattr 获取某个属性的值

setattr 新增或修改某个属性

delattr 删除某个属性

案例:

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)

       method()

   else:

       print("sorry this method is not exists....!")

 

动态导入模块

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

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

import importlib

mk = importlib.import_module(m_name)

mk 即导入成功的模块

"""

该方式常用在框架中 因为框架设计者不可能提前预知后续需要的模块和类

 

 

 

 

  

转载于:https://www.cnblogs.com/sry622/p/10896914.html

更多相关:

  • 文档树Document Object Model (DOM) 为文档对象模型, 它使用对象的表示方式来表示对应的文档结构及其中的内容。下面为一个样例 p 元素在文档中的对象所包含的所有属性。控制台:p#domaccessKey: ""align: ""assignedSlot: nullattributeStyleMap: Style...

  • jquery:js框架; 主要区别在dom的操作 jq需要引入文件并且引入顺序在最上面; 找元素 操作元素 js:doucument.getElementById..classname,tagname,name jq:$(选择器) dom是js对象 jqDom是jquery对象 操作内容 js:dom.innerHTML(非表单元素)...

  • Mock.js 的语法规范包括两部分: 数据模板定义规范(Data Template Definition,DTD)数据占位符定义规范(Data Placeholder Definition,DPD)1.数据模板定义规范 DTD 数据模板中的每个属性由 3 部分构成:属性名、生成规则、属性值: // 属性名 name // 生...

  • vue   vue.js 是用于构建交互式的 Web 界面的库。它提供了 MVVM 数据绑定和一个可组合的组件系统,具有简单、灵活的 API。从技术上讲, Vue.js 集中在 MVVM 模式上的视图模型层,并通过双向数据绑定连接视图和模型。实际的 DOM 操作和输出格式被抽象出来成指令和过滤器。相比其它的 MVVM 框架,Vue.j...

  • 栈可以分为 顺序栈: 数组实现链式栈: 链表实现空间复杂度 栈的空间复杂度: 有一个n个元素的栈, 在入栈和出栈过程中, 只需要存储一个临时变量存储空间, 所以空间复杂度是O(1) 并不是说栈有n个元素, 空间复杂度就是O(n), 而是指除了原本的空间外, 算法需要的额外空间 栈要满足后进先出(LIFO)的特性, 栈有以下几种方法...

  • 什么是闭包   python中函数名是一个特殊的变量,它可以作为另一个函数的返回值,而闭包就是一个函数返回另一个函数后,其内部的局部变量还被另一个函数引用。   闭包的作用就是让一个变量能够常驻内存。 def count():fs = []for i in range(1, 4):def f():return i*ifs.appen...

  • 最近尝试了一下Android的Gradle打包,发现确实比Ant打包会方便很多,特此记录下来。 注:android的gradle现在插件的版本已经是0.14.3了,对于一些老的方法和api,有一些已经被移除,无法使用(http://tools.android.com/tech-docs/new-build-system/migrati...

  • class str(basestring):"""str(object='') -> stringReturn a nice string representation of the object.If the argument is a string, the return value is the same object."""d...

  • 目录结构: contents structure [-] 类的基本使用专有方法继承单重继承多重继承砖石继承 1.类的基本使用 下面是类使用的一个简单案例, class person:"person 类的描述信息"def __init__(self,name="",age=0):self.name = nameself.age =...

  • 一、反射 反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。 python面向对象中的反射:通过字符串的形式操作对象相关的属性。pytho...

  • 一、set集合的方法 set不是特别常用,但是set的一些特性可以方便处理一些特殊情况。 集合(set)是一个无序不重复元素的序列。 可以使用大括号 { } 或者 set() 函数创建集合,注意:创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典。 创建格式: parame = {value01,va...

  • 1>UITextField实现leftView: self.inputTextField = [[UITextField alloc]initWithFrame:CGRectMake(10, 10, 200, 25)];self.inputTextField.delegate = self;self.inputTextField....