首页 > 其他分享 >面向对象封装/多态/反射

面向对象封装/多态/反射

时间:2022-11-07 18:46:17浏览次数:48  
标签:__ 封装 name self 多态 datetime 面向对象 print def

内容概要

  • 派生方法实战
  • 面向对象三大特性之封装
  • 三大特性之多态
  • 面向对象之反射
  • 反射实战案例
  • 练习题

派生方法实战

派生方法实战案例:
import json
import datetime


# time_dict = {'t1': datetime.datetime.today(),
#              't2': datetime.date.today()}
#
# res = json.dumps(time_dict)  # 序列化字典
# print(res)  # 结果报错,是因为字典内的日期类型不支持序列化
# '''raise TypeError(f'Object of type {o.__class__.__name__} '
# TypeError: Object of type datetime is not JSON serializable'''

# 我们就可以通过派生方法将上述字典转换成序列化,我们先看一下简单的
# time_dict = {'t1': str(datetime.datetime.today()),
#              't2': str(datetime.date.today())}  # 我们可以通过将日期类型转换为 字符串
# res = json.dumps(time_dict)  # 序列化字典
# print(res)  # 这样就可以得到最后序列化日期类型的结果
# # {"t1": "2022-11-07 14:47:27.634664", "t2": "2022-11-07"}

# 我们在看一下派生方法是怎么做到的
class My_JSONEncoder(json.JSONEncoder):
    def default(self, o):
        if isinstance(o, datetime.datetime):  # 判断传入的数据是否为日期类型
            return o.strftime('%Y-%m-%d %X')
        elif isinstance(o, datetime.date):
            return o.strftime('%Y-%m-%d')
        else:
            return super().default(o)


time_dict = {'t1': datetime.datetime.today(),
             't2': datetime.date.today()}
res = json.dumps(time_dict, cls=My_JSONEncoder)
print(res)
# {"t1": "2022-11-07 14:55:46", "t2": "2022-11-07"} 也成功的序列化了这个日期类型

# 我们使用这个派生方法就相当于改写了 json.JSONEcoder 里面的 default 方法
# 所以我们就可以通过改写方法来让我们序列化的字典不报错

面向对象之封装

封装:
	将数据与功能封装起来
    
    
class MyClass:
    school_name = '清华大学'
    _ = 'a'
    _name = 'Nicki_Minaj'
    __hobby = 'study'
    '''类在定义阶段 名字前面有两个下划线,那么它就会被隐藏起来,我们不能通过对象.的方式访问此数据值'''
    def __choice_num(self):
        pass

obj = MyClass()
print(obj.school_name)  # 清华大学
# print(obj.__hobby)  # 'MyClass' object has no attribute '__hobby'
# 虽然我们使用__hobby 不可以通过对象.的方式访问
# 我们看一下对象的名称空间
print(MyClass.__dict__)  # '_MyClass__hobby': 'study'
# 还是有__hobby 这个名字的
# 所以我们想访问的话就可以通过点的方式
print(MyClass._MyClass__hobby)  # study
# 但是我们这样虽然访问到了这个隐藏的属性,但是就失去了我们使用封装特性的目的了


隐藏:
	将数据和功能隐藏起来不让用户直接调用 而是开发一些接口间接调用,从而可以在接口内添加额外的操作
    
class Person:
    def __init__(self,name,gender):
        self.__name = name
        self.__gender = gender

    def walk(self):
        print(f'{self.__name} 会走路')
    def set_person(self,new_name):
        if len(new_name) == 0:
            raise ValueError('用户名长度不能为0')
        if new_name == '1':
            raise ValueError('用户名中不能些数字') 
        self.__name = new_name
'''我们封装是可以在类的定义阶段使用的'''
'''但是我们在类外就不可以进行对封装的属性修改或增加的操作了'''
# 隐藏的属性开放修改的接口 我们可以自定义很多功能
# 所以隐藏属性后,我们可以暴露给用户一些接口,让用户校验后才可以对属性进行修改    
    
    
伪装:
	将类里面的方法伪装成类利的数据  @property
    class Person(object):
    def __init__(self, name, height, weight):
        self.name = name
        self.height = height
        self.weight = weight
    @property
    def BMI(self):
        return self.weight / (self.height ** 2)


p1 = Person('jason', 1.83, 78)
# p1.BMI()  # BMI应该作为人的基本数据而不是方法
# print(p1.BMI)  # 利用装饰器伪装成数据
   

面向对象之多态

多态就代表着事物的多种形态
比如 水 :
有固态 气态 液态
#  面向对象中多态意思是 一种事物可以有多种形态但是针对相同的功能应该定义相同的方法
#  这样无论我们拿到的是哪个具体的事物 都可以通过相同的方法调用功能

鸭子类型

# 鸭子类型:只要你看上去像鸭子 走路像鸭子 说话像鸭子 那么你就是鸭子
'''python永远提倡自由简介大方 不约束程序员行为 但是也为多态提供了约束的方法'''
import abc

# 指定metaclass属性将类设置为抽象类,抽象类本身只是用来约束子类的,不能被实例化
class Animal(metaclass=abc.ABCMeta):
    @abc.abstractmethod  # 该装饰器限制子类必须定义有一个名为talk的方法
    def talk(self):  # 抽象方法中无需实现具体的功能
        pass

class Cat(Animal):  # 但凡继承Animal的子类都必须遵循Animal规定的标准
    def talk(self):
        pass

cat = Cat()  # 若子类中没有一个名为talk的方法则会抛出异常TypeError,无法实例化

面向对象之反射

反射:
在 python中 反射就是利用字符串去操纵对象的数据和方法
hasattr()  # 判断对象中是否含有某个字符串对应的属性名或方法名 返回布尔值

getattr() # 根据字符串获取对象中的属性名或方法名,如果没有就会报错
所以 getattr 方法一般 搭配 hasattr() 方法一起使用

setattr()  # 根据字符串给对象设置或修改数据

delattr() # 根据字符串删除对象里面的名字


class F1:
    def __init__(self,name,age):
        self.name = name
        self.name = name
    def talk(self):
        print(f'{self.name} 正在说话~')

obj = F1('kevin',123)
while True:
    func = input('请输入您想要执行的功能>>>:')
    if hasattr(obj,func):
        res = getattr(obj,func)
        res()
        break
    else:
        print('没这个功能')
        
        
# 我们再来看看反射的实战案例
class WinCmd:
    def tasklist(self):
        print('''
        tasklist功能正在运行
        ''')
    def ipconfig(self):
        print('''
        ip地址正在打印
        ''')
    def server_run(self):
            print('欢迎进入简易版本cmd终端')
            while True:
                target_cmd = input('请输入您的指令>>>:')
                res = target_cmd
                if  len(res) <= 1:
                    if hasattr(self, res[0]):
                        getattr(self, res[0])()
                    else:
                        print(f'{res[0]}不是内部或者外部命令')
     		   else:
                	print('没有这个功能~')
                    
obj = WinCmd()
obj.server_run()


一切皆对象
# 利用反射保留某个py文件中所有的大写变量名及对应的数据值
import settings  # 导入settings模块
print(dir(settings))  # dir列举对象可以使用的名字

useful_dict = {}
for name in dir(settings):
    if name.isupper():
        useful_dict[name] = getattr(settings, name)
        print(useful_dict)

 # while True:
#     target_name = input('请输入某个名字')
#     if hasattr(settings, target_name):
#         print(getattr(settings, target_name))
#     else:
#          print('该模块文件中没有该名字')

标签:__,封装,name,self,多态,datetime,面向对象,print,def
From: https://www.cnblogs.com/ddsuifeng/p/16866985.html

相关文章

  • Python——面向对象(封装、多态、反射)
    Python——面向对象派生方法实战#coding:utf-8importjsonimportdatetime#dict_demo={#'t1':datetime.date.today(),#'t2':datetime.datetime.to......
  • 面向对象3之封装多态映射
    目录派生方法实战演练面向对象三大特性之封装伪装三大特性之多态面向对象之反射反射实战案例派生方法实战演练importjsonimportdatetimed={'t1':datetime.da......
  • 面向对象之派生方法、封装、伪装、三大特性、反射
    面向对象之派生方法、封装、伪装、三大特性、反射派生方法实战演练什么是派生方法?子类中的定义方法和父类定义方法一模一样的方法,并且扩展了新功能(子类和父类一样,但是......
  • APICloud实战案例:如何封装AVM组件?(以声网组件为例)
    AVM.js(Application-View-Model)是一个移动优先的高性能跨端JavaScript框架,支持一次编写多端渲染。它提供更趋近于原生的编程体验,通过简洁的模型来分离应用的用户界面、业......
  • 封装去重的方法
    封装的方法1.去除同一数组中对象属性相同的对象fn(array,key){letseen=newSet();returnarray.filter((item)=>{letk=key(item);......
  • python二十九课--对象的封装与多态等知识
    上周内容回顾动静态方法类体代码中编写的函数有三种类型1.绑定给对象的方法:对象调用自动当做第一个参数传入 类中直接定义函数 classC1:def......
  • 封装MyBatis输出结果-简单类型,对象类型,map,resulemap,模糊查询
    封装MyBatis输出结果resultType:执行sql得到ResultSet转换的类型,使用类型的完全限定名或别名。注意如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身......
  • 多态
    多态注意事项:1.多态是方法的多态,属性没有多态2.父类和子类,有联系,类型转换异常 4.static方法不能被重写,属于类,不属于实例5.final修饰的方法不能被重......
  • PyQt5中处理自定义槽的手段(对于界面继承的封装)
    自定义槽由于我打算用QT编辑器来设计Qt界面,所以少不了ui转py的这一步骤。但是每次转ui时,都会自动覆盖原来的文件,这样的话,如果需要在源文件的基础上添加自定义槽,就很麻烦......
  • 面向对象
    目录一、面向对象概念引入(人狗大战)人狗大战简介推导步骤1:代码定义出人和狗推导步骤2:将产生人和狗的字典封装成函数并封装人和狗的攻击函数推导步骤3:人和狗的攻击混乱二......