Python面向对象06 /元类type、反射、函数与类的区别、特殊的双下方法

1. 元类type

  • type:获取对象从属的类

    Python中一切皆对象,类在某种意义上也是一个对象

    Python中自己定义的类,以及大部分内置类,都是由type元类(构建类)实例化得来的

    # type 获取对象从属于的类
    print(type(A))
    print(type(str))
    print(type(dict))
  • type与object的关系:

    object类是type类的一个实例 print(type(object))

    object类是type类的父类 print(issubclass(type,object))

2. 反射

  • 定义:通过字符串操作对象的方式,程序对自己内部代码的一种自省方式

  • 内置函数:hasattr getattr setattr delattr (attr 是属性的意思)

  • 反射可以作用的对象:实例对象,类,本模块,其他模块

    从对象角度应用反射

    class A:
    country = '中国'
    def __init__(self,name,age):
    self.name = name
    self.age = age
    def func(self):
    print('in A func')
    obj = A('张三',66) # hasattr: 判断有无属性
    print(hasattr(obj,'name'))
    print(hasattr(obj,'country')) # 报错
    print(hasattr(obj,'func')) # 报错 # getattr: 获取属性
    if hasattr(obj,'name'):
    getattr(obj,'name') # setattr: 设置属性/delattr: 删除属性
    setattr(obj,'sex','男')
    delattr(obj,'name')

    从类的角度应用反射

    class A:
    country = '中国'
    def __init__(self,name,age):
    self.name = name
    self.age = age
    def func(self):
    print(self)
    print('in A func') if hasattr(A,'func'):
    obj = A('张三', 26)
    getattr(obj,'func')()
    getattr(A,'func')(obj)

    从其他模块应用反射

    import tbjx
    
    # 1. 找到tbjx对象的C类,实例化一个对象.
    obj = getattr(tbjx,'C')('123') # 2. 找到tbjx对象的C类,通过对C类这个对象使用反射取到area.
    print(getattr(tbjx.C,'area')) # 3. 找到tbjx对象的C类,实例化一个对象,对对象进行反射取值.
    obj = getattr(tbjx,'C')('张三')
    print(obj.name)
    print(getattr(obj,'name'))

    从当前模块应用反射

    def func1():
    print('in func1') def func2():
    print('in func2') def func3():
    print('in func3') def func4():
    print('in func4') import sys
    print(sys.modules[__name__])
    getattr(sys.modules[__name__],'func1')()
    getattr(sys.modules[__name__],'func2')()
    getattr(sys.modules[__name__],'func3')() # 本模块的模块名:sys.modules[__name__]
  • 反射应用示例:

    class User:
    def login(self):
    print('欢迎来到登录页面') def register(self):
    print('欢迎来到注册页面') def save(self):
    print('欢迎来到存储页面') choose_dic = {
    1: User.login,
    2: User.register,
    3: User.save,
    } while 1:
    choose = input('请输入序号: \n1: 登录\n2: 注册\n3: 存储').strip()
    obj = User()
    choose_dic[int(choose)](obj)

3. 函数与类的区别

  • 函数都是显性传参,方法都是隐形传参

    class A:
    @classmethod
    def func(cls,a):
    pass
    @staticmethod
    def func1():
    pass A.func(666)
    A.func()
  • 通过打印函数名的方式,区别什么是方法,什么是函数

    def func1():
    pass
    class A:
    def func(self):
    pass
    print(func1)
    print(A.func)
    obj = A()
    print(obj.func) # 结果:
    <function func1 at 0x000000A9C59C1EA0>
    <function A.func at 0x000000A9C75DE268>
    <bound method A.func of <__main__.A object at 0x000000A9C744D4A8>>
  • 可以借助模块判断类中的是方法还是函数

    from types import FunctionType
    from types import MethodType
    def func():
    pass
    class A:
    def func(self):
    pass
    obj = A()
    print(isinstance(func,FunctionType)) # True
    print(isinstance(A.func,FunctionType)) # True
    print(isinstance(obj.func,FunctionType)) # False
    print(isinstance(obj.func,MethodType)) # True

4. 特殊的双下方法

  • 特殊的双下方法: 原本是开发python这个语言的程序员用的.源码中使用的,双下方法: 你不知道你干了什么就触发某个双下方法

    # 1.__len__   len(b)执行b类从属父类的__len__方法,必须要有return int(返回值)
    class B:
    def __init__(self,name,age):
    self.name = name
    self.age =age
    def __len__(self):
    return len(self.__dict__) # 2
    b = B('张三',28)
    print(len(b)) # 2.__hash__ hash()触发__hash__双下方法
    class A(object):
    def __hash__(self):
    return 123456
    obj = A()
    print(hash(obj)) # 3.__str__ 里边必须有return "字符串"类型 (优先级高于__repr__)
    # - 打印对象的时候,会触发__str__方法
    # - str转化也可以触发
    class A:
    def __init__(self,name,age):
    self.name = name
    self.age =age
    def __str__(self):
    print('触发str方法')
    return f'姓名: {self.name} 年龄: {self.age}'
    a = A('张三',35) # 打印对象触发__str__方法
    print(f'{a.name} {a.age}')
    print(a) # 直接str转化也可以触发.
    print(str(a)) # 4.__repr__ 里边必须有return "字符串"类型
    # - 打印对象的时候,会触发__repr__方法
    class A:
    def __init__(self,name,age):
    self.name = name
    self.age =age
    def __repr__(self):
    print(666)
    return f'姓名: {self.name} 年龄: {self.age}' a = A('张三',35)
    print(a)
    print(repr(a)) # 5.__call__ 对象()触发对象从属类(父类)的__call__方法
    class Foo:
    def __init__(self):
    pass
    def __call__(self, *args, **kwargs):
    print('__call__')
    obj = Foo()
    obj() # 6.__eq__ 两对象==时触发,return True/false(可以返回数字,字符串 一般返回布尔值)
    class A(object):
    def __init__(self):
    self.a = 1
    self.b = 2 def __eq__(self,obj):
    print('__eq__')
    return True
    x = A()
    y = A()
    print(x == y) # 7.__del__ 析构方法 回收对象时触发__del__方法
    class A:
    def __del__(self):
    print('__del__')
    obj = A()
    del obj # 8.__new__ new一个对象(构造方法),实例化对象的时候会触发,对象是object类的__new__方法,产生了一个对象
    class A(object):
    def __init__(self):
    print('in init function') def __new__(cls, *args, **kwargs):
    print('in new function')
    return object.__new__(A) # 对象是object类的__new__方法 产生了一个对象.
    a = A() # 类名()
    # 1. 先触发 object的__new__方法,此方法在内存中开辟一个对象空间.
    # 2. 执行__init__方法,给对象封装属性. # def __init__(self):(不能写返回值,因为__new__已经有返回值了,不能同时接收两个返回值,只能接收__new__的返回值) # 9.__item__系列(4个)
    # __getitem__ __setitem___ __delitem__ 对对象做类似于字典的(增删改查)触发__item__系列
    class Foo:
    def __init__(self,name):
    self.name=name
    def __getitem__(self, item):
    # print(item)
    # print(666)
    return self.__dict__[item] def __setitem__(self, key, value):
    # self.__dict__[key]=value
    print(key)
    print(value) def __delitem__(self, key):
    print('del obj[key]时,我执行') f1=Foo('zhangsan')
    f1['age']
    f1[1] = 2
    del f1[1] # 10.__enter__ __exit__ with 上下文管理(2个)
    class A: def __init__(self, text):
    self.text = text def __enter__(self): # 开启上下文管理器对象时触发此方法
    self.text = self.text + '您来啦' # 第一步
    print(11111)
    return self # 必须!!!将实例化的对象返回f1 def __exit__(self, exc_type, exc_val, exc_tb): # 执行完上下文管理器对象f1时触发此方法
    print(333) # 第三步
    self.text = self.text + ',这就走啦' with A('大爷') as f1:
    print(2222)
    print(f1.text) # 第二步
    print(f1.text) # 第四步 # 11.__iter__ for循环会触发此方法
    class A:
    def __init__(self,name):
    self.name = name def __iter__(self):
    for i in range(10):
    yield i obj = A('张三')
    for i in obj:
    print(i) # 12.__getattr__(self,item),__setattr__(self,key,value),__delattr__
    # obj.属性会触发__getattr__(self,item)方法
    # obj.属性=123 会触发__setattr__(self,key,value)
    # del obj.属性 就会触发__delattr__ 此方法

Python面向对象06 /元类type、反射、函数与类的区别、特殊的双下方法的更多相关文章

  1. python 面向对象专题(六):元类type、反射、函数与类的区别、特殊的双下方法

    目录 Python面向对象06 /元类type.反射.函数与类的区别.特殊的双下方法 1. 元类type 2. 反射 3. 函数与类的区别 4. 特殊的双下方法 1. 元类type type:获取对象 ...

  2. day26——tyoe元类与object的联系、反射、函数与方法的区别、双下方法

    day26 type元类与object联系 type 获取对象从属于的类 python 中一切皆对象, 类在某种意义上也是一个对象,python中自己定义的类,以及大部分内置类,都是由type元类(构 ...

  3. python之面向对象函数与方法,反射,双下方法

    一.函数和方法 1.函数和方法的区别 函数: 全都是显性传参,手动传参,与对象无关 方法: 存在隐性传参,与对象有关 1.1通过函数名可以判断 len()就是函数 str.count()就是方法 de ...

  4. Python进阶----反射(四个方法),函数vs方法(模块types 与 instance()方法校验 ),双下方法的研究

    Python进阶----反射(四个方法),函数vs方法(模块types 与 instance()方法校验 ),双下方法的研究 一丶反射 什么是反射: ​ 反射的概念是由Smith在1982年首次提出的 ...

  5. Python面向对象之反射,双下方法

    一. 反射 反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省).这一概念的提出很快引发了计算机科学领域关于应用反射性的研究.它首先被程序 ...

  6. 百万年薪python之路 -- 面向对象之 反射,双下方法

    面向对象之 反射,双下方法 1. 反射 计算机科学领域主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省) python面向对象中的反射:通过字符串的形式操作对象相关的属性.python ...

  7. Python反射和内置方法(双下方法)

    Python反射和内置方法(双下方法) 一.反射 什么是反射 反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省).这一概念的提出很快引发 ...

  8. Python面向对象 | 双下方法

    定义:双下方法是特殊方法,他是解释器提供的.由双下划线+方法名+双下划线 .它具有特殊意义的方法,双下方法主要是python源码程序员使用的,我们在开发中尽量不要使用双下方法,但是深入研究双下方法,更 ...

  9. C++类的成员函数(在类外定义成员函数、inline成员函数)

    类的成员函数(简称类函数)是函数的一种,它的用法和作用和前面介绍过的函数基本上是一样的,它也有返回值和函数类型,它与一般函数的区别只是:它是属于一个类的成员,出现在类体中.它可以被指定为private ...

随机推荐

  1. Python多线程 - threading

    目录 1. GIL 2. API 3. 创建子线程 4. 线程同步 4.1. 有了GIL,是否还需要同步? 4.1.1. 死锁 4.1.2. 竞争条件 4.1.3. GIL去哪儿了 4.2. Lock ...

  2. (一)JDK安装和使用eclipse输出hello world

    目录 一.jdk安装(推荐使用压缩包安装) 二.使用eclipse输出hello world 一.jdk安装(推荐使用压缩包安装) 1.压缩包安装的优点:若可能同时使用多个jdk版本,切换jdk时只需 ...

  3. excel如何快速计算日期对应的生肖?

      是否可以根据日期统计出生肖? 牛闪闪想应该可以吧!结果搜到了一个巨牛无比的公式. =MID("猴鸡狗猪鼠牛虎兔龙蛇马羊",MOD(YEAR(B2),12)+1,1), 利用年份 ...

  4. centos7 hive 单机模式安装配置

    前言:由于只是在自己的虚拟机上进行学习,所以对hive只是进行最简单的配置,其他复杂的配置文件没有配置. 1.前提 1.1 安装配置jdk1.8 1.2 安装hadoop2.x hadoop单机模式安 ...

  5. LR字符串处理函数-lr_save_var

    int lr_save_var ("截取的字符串"+start,len,options,param_name) start:表示从第几位截取  len:表示截取长度  option ...

  6. 030.Kubernetes核心组件-Scheduler

    一 Scheduler原理 1.1 原理解析 Kubernetes Scheduler是负责Pod调度的重要功能模块,Kubernetes Scheduler在整个系统中承担了"承上启下&q ...

  7. 【JMeter_06】JMeter逻辑控制器__If控制器<If Controller>

    If控制器<If Controller> 业务逻辑: 根据表达式的结果来决定是否执行控制器下的脚本内容,与编程语言中的if判断逻辑大致相同,表达式结果为布尔值 true或false; 当表 ...

  8. IDEA之maven配置详解

    这两天被maven配置搞得焦头烂额,前后忙活了三天才彻底搞定. 下面我总结一下配置的步骤. 步骤 1. 首先去maven官网去下载maven,http://maven.apache.org/ 这里教大 ...

  9. Jmeter Response Data 乱码问题解决方法

    1. 进入jmeter\apache-jmeter-4.0\bin,打开jmeter.properties 2. 搜索“sampleresult.default.encoding” 设置sampler ...

  10. Beta冲刺<2/10>

    这个作业属于哪个课程 软件工程 (福州大学至诚学院 - 计算机工程系) 这个作业要求在哪里 Beta冲刺 这个作业的目标 Beta冲刺--第二天(05.20) 作业正文 如下 其他参考文献 ... B ...