Python基础-week06 面向对象编程进阶

一.反射

  1.定义:指的是通过字符串来操作类或者对象的属性

  2.为什么用反射?

    减少冗余代码,提升代码质量。

  3.如何用反射?

    

class People:
    country=‘China‘
    def __init__(self,name):
        self.name=name

obj=People(‘jame‘)

#hasattr
#print(‘country‘ in People.__dict__)
print(hasattr(People,‘country‘))

#getattr
#print(People.__dict__[‘country‘])
#print(getattr(People,‘country)) #如果取不到值,会报错。
print(getattr(People,‘country‘,None)) #None如果取不到值不报错,返回None

#setattr
#obj.age=18
#print(obj.__dict__)
setattr(obj,‘age‘,18)
print(obj.__dict__) #{‘name‘: ‘jame‘, ‘age‘: 18}
setattr(People,‘x‘,111)
print(People.__dict__)
#{......, ‘__doc__‘: None, ‘x‘: 111}

#delattr
delattr(People,‘x‘)
print(People.__dict__)
#{......, ‘__doc__‘: None}

例1:反射涉及的4个内置函数

class Ftp:
    def get(self):
        print(‘get...‘)

    def put(self):
        print(‘put...‘)

    def auth(self):
        print(‘auth...‘)

    def run(self):
        while True:
            cmd=input(‘Please input:‘).strip() #cmd=‘get
            if hasattr(self,cmd):
                method=getattr(self,cmd)
                method()

            else:
                print(‘You please input error‘)

obj=Ftp()
obj.run()

例2:反射的简单使用

  动态导入模块<了解>:

  

  

import importlib

__import__(‘import_lib.metaclass‘) #这是解释器自己内部用的
#importlib.import_module(‘import_lib.metaclass‘) #与上面这句效果一样,官方建议用这个

  

二.一些内置方法 和 函数介绍

  1.isinstance(obj,cls)和issubclass(sub,super)

    isinstance(obj,cls)检查是否obj是否是类 cls 的对象。

    issubclass(sub,super) 检查sub类是否是 super类的派生类。    

class Foo(object):
    pass

class bar(Foo):
    pass

obj=Foo()

#1 isinstance判断对象是否属于某类
res1=isinstance(obj,Foo)
print(res1) #True

#2 issubclass 判断bar类是否是 Foo 类的派生类
res2=issubclass(bar,Foo)
print(res2) #true

  2.__setattr__ ,__delattr__ ,__getattr__

   配合反射机制使用,效果还不错. 

class People:
    country=‘China‘
    def __init__(self,name):
        self.name=name

obj=People(‘jame‘)

#hasattr
#print(‘country‘ in People.__dict__)
print(hasattr(People,‘country‘))

#getattr
#print(People.__dict__[‘country‘])
#print(getattr(People,‘country123‘)) #如果取不到值,会报错。AttributeError: type object ‘People‘ has no attribute ‘country123‘
print(getattr(People,‘country123‘,None)) #None如果取不到值不报错,返回None

#setattr
#obj.age=18
#print(obj.__dict__)
setattr(obj,‘age‘,18)
print(obj.__dict__) #{‘name‘: ‘jame‘, ‘age‘: 18}
setattr(People,‘x‘,111)
print(People.__dict__)
#{......, ‘__doc__‘: None, ‘x‘: 111}

#delattr
delattr(People,‘x‘)
print(People.__dict__)
#{......, ‘__doc__‘: None}

在类外部使用实例 

class Foo:
    x=1

    def __init__(self,y):
        self.y=y

    def __getattr__(self, item):
        print(‘from getattr:你找的属性不存在.‘)

    def __setattr__(self, key, value):
        print(‘from setattr‘)

    def __delattr__(self, item):
        print(‘from delattr‘)
        self.__dict__.pop(item)

#1 __setattr__ 添加、修改属性会触发它的执行
f1=Foo(10) #from setattr
print(f1.__dict__) #{}
#因为你重写了__setattr__,凡是赋值操作都会触发它的运行,你啥都没写,就是根本没赋值,除非你直接操作属性字典,否则永远无法赋值
f1.__dict__[‘a‘]=3
f1.__dict__[‘b‘]=4
print(f1.__dict__) #{‘a‘: 3, ‘b‘: 4}

#2 __deattr__ 删除属性的时候会触发
#f1.__dict__[‘a‘]=10 #我们可以通过修改属性字典,来完成添加、修改属性的操作
del f1.a #from delattr
print(f1.__dict__) #{‘b‘:4}还剩b

# 3 __getattr__ 只有使用点调用属性且属性不存在的时候才会触发
f1.abc #from getattr:你找的属性不存在.

class Ftp:
    def get(self):
        print(‘get...‘)

    def put(self):
        print(‘put...‘)

    def auth(self):
        print(‘auth...‘)

    def run(self):
        while True:
            cmd=input(‘Please input:‘).strip() #cmd=‘get
            if hasattr(self,cmd):
                method=getattr(self,cmd)
                method()

            else:
                print(‘You please input error‘)

obj=Ftp()
obj.run()

配合反射使用实例

  3.__getattribute__

    

# @Time    : 2018/8/20 17:19
# @Author  : Jame
# class Foo:
#     def __init__(self,x):
#         self.x=x
#
#     def __getattr__(self, item):
#         print(‘执行的是__getattr__‘)
#
#
#
#
# f1=Foo(100)
# print(f1.x)
# f1.xxx #若访问的不存在,则 “执行的是__getattr__”

class Foo:
    def __init__(self,x):
        self.x=x

    def __getattribute__(self, item):
        print(‘不管是否存在都执行的是__getattribute__‘)

f1=Foo(200)
f1.x
f1.xxx

getattr与getattribute的使用

class Foo:
    def __init__(self,x):
        self.x=x

    def __getattr__(self, item):
        print(‘如果不存在则执行__getattr__‘)

    def __getattribute__(self, item):
        print(‘不管是否存在都执行的是__getattribute__‘)
        raise AttributeError(‘哈哈 嘿嘿 哟哟‘)

f1=Foo(200)
f1.x
f1.xxx

getattr和getattribute同时存在实例

#当__getattribute__与__getattr__同时存在,只会执行__getattrbute__,除非__getattribute__在执行过程中抛出异常AttributeError

  4.描述符(__get__,__set__,__delete__)

    (1).1 描述符是什么?

      描述符本质就是一个新式类,在这个新式类中,至少实现了__get__(),__set__(),__delete__()中的一个,这也被称为描述符协议
      __get__():调用一个属性时,触发
      __set__():为一个属性赋值时,触发
      __delete__():采用del删除属性时,触发

   

#1 定义一个描述符
class Foo:
    def __get__(self, instance, owner):
        print(‘__get__‘)

    def __set__(self, instance, value):
        print(‘__set__‘)

    def __delete__(self, instance):
        print(‘__delete__‘)

定义一个描述符

    (2).描述符是干什么的,何时触发描述符中的3个方法呢?

      描述符的作用是用来代理另外一个类的属性的(必须把描述符定义成这个类的类属性,不能定义到构造函数中__init__())

      包含这三个方法的新式类称为描述符,由这个类产生的实例进行属性的调用/赋值/删除,并不会触发这三个方法!例如:

      

#2 描述符的使用
class Foo2:
    def __get__(self, instance, owner):
        print(‘触发 __get__‘)

    def __set__(self, instance, value):
        print(‘触发 __set__‘)

    def __delete__(self, instance):
        print(‘触发 __delete__‘)

#包含这三个方法的新式类称为描述符,由这个类产生的实例进行属性的调用/赋值/删除,并不会触发这三个方法!
f2=Foo2()
f2.name=‘jame‘
print(f2.name)
del f2.name

描述符的实例进行调用/赋值/删除不会触发

      

      #何地?:定义成另外一个类的类属性

      #何时?:且看下列演示

class Str:
    def __get__(self, instance, owner):
        print(‘Str 调用‘)

    def __set__(self, instance, value):
        print(‘str 设置‘)

    def __delete__(self, instance):
        print(‘str 删除‘)

class Int:
    def __get__(self, instance, owner):
        print(‘Int 调用‘)

    def __set__(self, instance, value):
        print(‘Int 设置‘)

    def __delete__(self, instance):
        print(‘Int 删除‘)

class People:
    name=Str()
    age=Int()

    def __init__(self,name,age): #name 被设置为Str类的的代理,age被设置Int类的代理。
        self.name=name
        self.age=age

#何地?:定义成另外一个类的类属性

#何时?:且看下列演示

p1=People(‘jame‘,18) #触发Str 设置,Int 设置!

#1 描述符str的使用 调用,设置,删除
#p1.name
#p1.name=‘tom‘
#del p1.name
‘‘‘
Str 调用
str 设置
str 删除
‘‘‘

#2 描述符int的使用  调用,设置,删除
#p1.age
#p1.age=30
#del p1.age
‘‘‘
Int 调用
Int 设置
Int 删除
‘‘‘

#3 我们来瞅瞅到底发生了什么?
print(p1.__dict__)
print(People.__dict__)

#补充
print(type(p1) == People) #True,type(p1) 查看p1是哪个类实例化来的。
print(type(p1).__dict__==People.__dict__) #True

触发描述符的场景

 

    

    

    (3).描述符分两种

      1).数据描述符:至少实现了__get__()和__set__()      

1 class Foo:
2     def __set__(self, instance, value):
3         print(‘set‘)
4     def __get__(self, instance, owner):
5         print(‘get‘)

      2).非数据描述符:没有实现__set__()

  

class Foo:
2     def __get__(self, instance, owner):
3         print(‘get‘)

  (4).注意事项:
    一 描述符本身应该定义成新式类,被代理的类也应该是新式类
    二 必须把描述符定义成这个类的类属性,不能为定义到构造函数中
    三 要严格遵循该优先级,优先级由高到底分别是
      1.类属性
      2.数据描述符
      3.实例属性
      4.非数据描述符
      5.找不到的属性触发__getattr__()

      。。。。。。

  

三.元类

四.异常处理

原文地址:https://www.cnblogs.com/Jame-mei/p/9507442.html

时间: 2024-11-08 20:07:43

Python基础-week06 面向对象编程进阶的相关文章

Day6 - Python基础6 面向对象编程

Python之路,Day6 - 面向对象学习 本节内容: 面向对象编程介绍 为什么要用面向对象进行开发? 面向对象的特性:封装.继承.多态 类.方法. 引子 你现在是一家游戏公司的开发人员,现在需要你开发一款叫做<人狗大战>的游戏,你就思考呀,人狗作战,那至少需要2个角色,一个是人, 一个是狗,且人和狗都有不同的技能,比如人拿棍打狗, 狗可以咬人,怎么描述这种不同的角色和他们的功能呢? 你搜罗了自己掌握的所有技能,写出了下面的代码来描述这两个角色 1 2 3 4 5 6 7 8 9 10 11

Python基础6-1 面向对象编程

概述 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象:对函数进行分类和封装,让开发"更快更好更强..." 面向过程编程最易被初学者接受,其往往用一长段代码来实现指定功能,开发过程中最常见的操作就是粘贴复制,即:将之前实现的代码块复制到现需功能处. while True:     if cpu利用率 > 90%:         #发送邮件提醒         连接邮箱服务器         发送邮件     

Python基础day-16[面向对象编程(未完)]

面向对象: 相对于面向过程编程来讲,面向对象的扩展性比较强.但是同时带来的问题是可控性差,面向对象编程不像面向过程那样可以很精准的预测结果.面向对象程序一旦开始就由对象之间进行交互解决问题. 面向对象程序设计只是用来解决程序扩展性的. 什么是对象: 举一个例子:每个人都有自己特征和技能,那么每个人就是一个对象.对象就是特征与技能的结合体. 什么是类: 每个人都有自己独有特征也有和别人同样的技能或者特征.例如:基本每个人都会吃饭,都会睡觉,都会说话或者某两个人眼睛都挺大.我们可以把这些共同的技能或

Python基础-第六天-面向对象编程

本篇内容 1.面向对象编程介绍 2.类的定义及各部分的介绍 3.属性 4.方法 5.面向对象的特性-封装 6.面向对象的特性-继承 7.面向对象的特性-多态 8.新式类和经典类 一.面向对象编程介绍 1.编程的原则 无论用什么编程范式来编程都要记住的原则是,避免写重复代码,代码要易扩展.一定要遵循可读性好.易扩展的原则. 2.面向对象编程(Object-Oriented Programming)介绍 OOP编程的主要作用是使代码修改和扩展变的更容易: 面向对象编程是利用类和对象来帮助我们实现功能

python基础之面向对象编程介绍、类和对象

面向对象变成介绍 面向过程编程 核心是过程(流水线式思维),过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么东西.主要应用在一旦完成很少修改的地方,如linux内核.git.apache服务器等 优点:极大的降低了程序的设计复杂度 缺点:可扩展性差,改动一个地方很可能要改多个地方,牵一发而动全身 面向对象编程:不是编程的全部,只是用来解决软件可扩展性的 核心是对象(上帝式思维),对象作为程序的基本单元,一个对象包含了数据和操作数据的函数.面向对象就是把计算

Python基础6 面向对象编程

本节内容: 面向对象编程介绍 为什么要用面向对象进行开发? 面向对象的特性:封装.继承.多态 类.方法. 引子 你现在是一家游戏公司的开发人员,现在需要你开发一款叫做<人狗大战>的游戏,你就思考呀,人狗作战,那至少需要2个角色,一个是人, 一个是狗,且人和狗都有不同的技能,比如人拿棍打狗, 狗可以咬人,怎么描述这种不同的角色和他们的功能呢? 你搜罗了自己掌握的所有技能,写出了下面的代码来描述这两个角色 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 def per

python基础之面向对象编程

面向对象编程思想 面向对象是一门编程思想,编程思想仅仅是一门思想,与任何技术无关 核心是对象两字,对象可以理解为特征与技能的结合体 基于该编程思想编写程序,就好比创造世界,一种造物主的思维方式 优点:可扩张性强 缺点:编写程序的复杂难度比面向过程高 以上都是纯理论,理解下用自己的话能编出来就行,下面来说说核心对象 在现实世界中,通过一个个的对象,根据相同的特征和行为,再分门别类. 但是在程序中,必须先有类,再通过调用类,创建对象. 那么,咱们如何定义类,又如何创建对象呢?(暂时还是先说理论吧,不

Python基础之面向对象(进阶篇)

面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使用(可以讲多函数中公用的变量封装到对象中) 对象,根据模板创建的实例(即:对象),实例用于调用被包装在类中的函数 面向对象三大特性:封装.继承和多态 本篇将详细介绍Python 类的成员.成员修饰符.类的特殊成员. 类的成员 类的成员可以分为三大类:字段.方法和属性 注:所有成员中,只有普通字段的内容保存对象中,即:根据此类创建了多少对象,在内存中就有多少个普通字段.而其他的成员,

Python基础6-2 面向对象编程

本篇将详细介绍Python 类的成员.成员修饰符.类的特殊成员. 类的成员 类的成员可以分为三大类:字段.方法和属性 注:所有成员中,只有普通字段的内容保存对象中,即:根据此类创建了多少对象,在内存中就有多少个普通字段.而其他的成员,则都是保存在类中,即:无论对象的多少,在内存中只创建一份. 一.字段 字段包括:普通字段和静态字段,他们在定义和使用中有所区别,而最本质的区别是内存中保存的位置不同, 普通字段属于对象 静态字段属于类 class Province:     # 静态字段     c