反射 双下方法

一 : 元类 type

  1. Type 获取对象从属的类
class A:
    pass
print(type('abc'))     #  <class 'str'>
print(type([1,2,3]))    #  <class 'list'>
print(type((22,33)))    #  <class 'tuple'>
  1. python 中一切皆对象,类在某种意义上也是一个对象,python 中自己定义的类,以及大部分内置类,都是由 type元类实例化得来的
  2. type 与 object 的关系

    object 是 type 类的一个实例

    object 是type类的父类

    print(issubclass(type,object))
    #  True

二 : 反射

  1. 程序对自己内部代码的一种自省
  2. 反射是什么?

    通过字符串去操作对象的方式

? 四种使用场所

? 实例对象

? 类

? 本模块

? 其他模块

  1. hasattr  getattr  setattr delattr

实例对象

hasattr : 判断是否存在,存在返回True,不存在返回 False

print(hasattr(obj,'name'))      #  True
print(hasattr(obj,'country'))   #  True
print(hasattr(obj,'func'))      #   True

getattr : 返回的是具体值,相当于取代那个万能的点

print(getattr(obj,'name'))      #  赵海狗

print(getattr(obj,'country'))   #  中国

print(getattr(obj,'func'))     #  <bound method A.func of <__main__.A object at 0x10a3d3b70>>

print(getattr(obj,'func')())   已经调用了这个函数了
# in A func
# None

print(getattr(obj,'sex',None))  #  指定查不到就返回 None
print(getattr(obj,'sex'))  # 报错

setattr : 相当于增加一个属性

setattr(obj,'sex','公')  #  增加一个
print(obj.__dict__)
# {'name': '赵海狗', 'age': 78, 'sex': '公'}

delattr : 删除一个属性

delattr(obj,'name')  # 删除里面的值
print(obj.__dict__)
{'age': 78, 'sex': '公'}
从类的角度
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,'country'):
#     print(getattr(A,'country'))  # 中国
if hasattr(A,'func'):
    obj = A('赵海狗',26)
    getattr(obj,'func')()            在对象中调用,隐性传参
#<__main__.A object at 0x10966c240>  在函数中调用,显性传参   两种是一样的
# in A func
   getattr(A,'func')(obj)
# <__main__.A object at 0x10966c240>
# in A func
从其他模块
import tbjx  (从其他文件导过来的)

# 1.找到tbjx对象的C类,实例化一个对象
# print(getattr(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')) #   赵海狗
tbjx 文件如下
name = '太白金星'

def func():
    print('in tbjx func')
class C:
    area = '北京'

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

    def func(self):
        print('in B func')

从当前模块研究反射

a = 666
def func():
    print('in 本模块这个对象')
def func1():
    print('in func1')
def func2():
    print('in func2')
def func3():
    print('in func3')
def func4():
    print('in func4')

# func1()
# func2()
# func3()
# func4()

import sys
print(sys.modules[__name__])
# <module '__main__' from '/Users/zhl/Desktop/python_24/day26/课堂练习.py'>
# 相当于一个字典   查找都有
print(getattr(sys.modules[__name__],'a'))
# 666

func_lst = [f'func{i}' for i in range(1,5)]
print(func_lst)
for func in func_lst:
    getattr(sys.modules[__name__],func)()

in func1
in func2
in func3
in func4

反射的应用
class User:
    user_list = [('login','登录'),('register','注册'),('save','存储')]
    def login(self):
        print('欢迎来到登录界面')
    def register(self):
        print('欢迎来到注册界面')
    def save(self):
        print('欢迎来到存储界面')
while 1:
    choose = input('请输入序号:\n1:登录\n2:注册\n3:存储\n').strip()
    obj = User()
    getattr(obj,obj.user_list[int(choose) - 1][0])()
    #  getattr(obj,'login)
#  这样简化代码 显得更高大上一些

三 : 函数与方法的区别

通过打印函数名的方式区别什么是方法,什么是函数(了解)

def func1():
    pass
class A:
    def func(self):
        pass
print(func1)
print(A.func)    #  通过类名调用的类中的实例方法叫做函数
obj = A()
print(obj.func) # 通过对象调用类中的实例方法叫做方法
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
#  所以这个类名调用的类中的实例方法叫做函数
#  通过对象调用类中的实例方法叫做方法

总结 :

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

以及大部分内置类,都是由type 元类实例化而来

Python 中一切皆对象,函数在某种意义上也是一个对象,函数这个对象是从 FunctionType这个实例化出来的

Python 中一切皆对象,方法在某种意义上也是一个对象,方法这个对象是从 MethodType这个类实例化出来的

如何判断类中的是方法还是函数 ? ?

class A:
    @classmethod
    def func(cls,a):  # 显性和隐性是从这里判断
        pass
    @staticmethod
    def func1( ):
        pass
A.func(222)
# A.func()
obj = A()
obj.func('是')
# 只要参数不对等,并且有 self  cls 就是隐性传参  函数

四 : 特殊的双下方法

用途 : 原本是开发Python这个语言的程序员用的,源码中使用

str : 我们不能轻易使用,慎用

双下方法 : 不知道触发某个方法走下去

__len__

class B:
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def __len__(self):
        print(self.__dict__)

        return len(self.__dict__)
b = B('liye',28)  #  {'name': 'liye', 'age': 28}
print(len(b))     # 2

print(len({'name':'liye','age':28}))   # 2

字典的话就是键值对的个数  其他就是元素的个数

__str__ 用来返回字符串表达式

class A:
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def __str__(self):
        print(666)
        return f'姓名:{self.name} 年龄:{self.age}'
a = A('赵海狗',35)
b = A('李业',33)
c = A('华丽',18)
#  打印对象触发 __str__
print(f'{a.name} {a.age}')  # 赵海狗 35
print(f'{b.name} {b.age}')  # 李业 33
print(f'{c.name} {c.age}')  # 华丽 18
print(a)
#666
# 姓名:赵海狗 年龄:35
print(b)
print(c)  

print(str(a))    直接 str 也可以触发
#666
# 姓名:赵海狗 年龄:35

打印了对象就触发了 str 所以是这个意思

__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)
b = A('李业',12)
c = A('华丽',18)
print(a)
print(repr(a))
# 666
# 姓名:赵海狗 年龄:35
# 666
# 姓名:赵海狗 年龄:35
# 两个结果是一样的
#  打印对象后也是触发 repr 吗?  他两有什么区别呢?和 str
print('我叫%s' % ('alex'))  # 我叫alex
print('我叫%r' % ('alex'))  # 我叫'alex'
print(repr('fdsaf'))        #  'fdsaf'

看这个结果是把字符串啥的引号都给表现出来了

_call_

**对象() 自动触发对象从属于类(父类)的__call__方法**

class Foo:
    def __init__(self):
        pass

    def __call__(self, *args, **kwargs):
        print('__call__')

obj = Foo()
obj()
#  __call__

_eq__

class A(object):
    def __init__(self):
        self.a = 1
        self.b = 2
    def __eq__(self,obj):
        if  self.a == obj.a and self.b == obj.b:
            return True
        # return True
x = A()
y = A()
print(x == y)
# True
两种比较

__del__

class A:
    def __del__(self):
        print(666)
obj = A()
del obj
#  666

_new_

class A(object):

    def __init__(self):

        self.x = 1
        print('in init function')

    def __new__(cls, *args, **kwargs):
        print('in new function')
        return object.__new__(A)  # object 342534

# # 对象是object类的__new__方法 产生了一个对象.
a = A()

#in new function
in init function

# 类名()
# 1. 先触发 object的__new__方法,此方法在内存中开辟一个对象空间.
# 2. 执行__init__方法,给对象封装属性.

我自己的理解是先执行 new  然后再执行 init

五 : python 中单例模式 重要必须会默写

class A:
    __instance = None

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

    def __new__(cls,*args,**kwargs):
        if not cls.__instance:
            cls.__instance = object.__new__(cls)
        return cls.__instance
obj = A('alex')
print(obj)
obj1 = A('李业')
print(obj1.name)
print(obj.name)
#  <__main__.A object at 0x106e8cf28>
# 李业
# 李业

原文地址:https://www.cnblogs.com/hualibokeyuan/p/11330872.html

时间: 2024-08-30 08:54:19

反射 双下方法的相关文章

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

一. 反射 反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省).这一概念的提出很快引发了计算机科学领域关于应用反射性的研究.它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩. python面向对象中的反射:通过字符串的形式操作对象相关的属性.python中的一切事物都是对象(都可以使用反射) 四个可以实现自省的函数 下列方法适用于类和对象(一切皆对象,类本身也是一个对象) class Foo:    f = '

面向对象之 元类 , 反射 , 双下方法

1.元类 type type元类,又称为构建类,python中一切皆对象,类也可以理解为对象,python中自己定义的类,以及大部分内置类,都是由type元类实例化得来的 元类type class A: pass obj = A() print(type('abc')) #<class 'str'> print(type([1,2,3])) #<class 'list'> print(type((22,33))) #<class 'tuple'> print(type(

面向对象之:元类,反射, 双下方法

[TOC] 1.元类 class A: pass obj = A() print(type('abc')) # <class 'str'> print(type([1,2,3])) # <class 'list'> print(type((22,33))) # <class 'tuple'> # type 获取对象从属于的类 print(type(A)) # <class 'type'> print(type(str)) # <class 'type'

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

一. 反射 反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省).这一概念的提出很快引发了计算机科学领域关于应用反射性的研究.它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩. python面向对象中的反射:通过字符串的形式操作对象相关的属性.python中的一切事物都是对象(都可以使用反射) 四个可以实现自省的函数 下列方法适用于类和对象(一切皆对象,类本身也是一个对象) 对实例化对象的示例 class Foo

面向对象的反射和双下方法(魔术方法)

反射: 通过字符串操作对象相关属性. 1 class Text: 2 def __init__(self,name,age): 3 self.name = name 4 self.age = age 5 def func(self): 6 print(123) 7 def func1(self): 8 return self 9 10 text = Text("小明",18) 11 print(hasattr(text,"func")) # 查看对象是否具有属性或方

面向对象之: 反射和双下方法

目录 一, 反射 二, 函数VS方法 三, 双下方法 一, 反射 反射:程序可以访问,检测和修改它本身状态或行为的一种能力(自省) python面向对象中的反射:通过字符串的形式操作对象相关的属性 python中的一切事物都是对象(都可以使用反射) 四个可以实现自省的函数,下列方法适用于类和对象(一切对象,类本身也是对象) # 对实例化对象的示例 class Foo: f = '类的静态变量' def __init__(self, name, age): self.name = name sel

面向对象:反射和双下方法

面向对象:反射和双下方法 1.元类type type:获取对象从属于的类 class A: pass obj = A() print(type(A)) print(type('abc')) print(type([1,2,3])) python中一切皆对象,类在某种意义上也是一个对象,python中自己定义的类,以及大部分内置类都是由type元类(构建类)实例化得来的 type 与 object 的关系 object类是type类的一个实例,object类是type的父类. print(type

面向对象中的双下方法

1.__str__与__repr__方法 class Animal: def __init__(self,name,age): self.name = name self.age = age def f(self): print("这是父类的方法") class Persion(Animal): country = "chinese" def __init__(self,name,age,sex): Animal.__init__(self,name,age) se

python之路-双下方法

双下方法 定义: 双下方法是特殊方法,他是解释器提供的,由双下线加方法名加双下划线 __方法名__具有特殊意义的方法 双下方法主要是Python源码程序员使用的,元编程 我们在开发中尽量不要使用双下方法,但是深入研究双下方法,更有益于我们阅读源码 1.__len__ 计算长度 s = 'nihaoashuaige' print(len(s)) #len作为内置函数,部分数据类型调用它的时候就会返回其长度,那是什么让这个函数起了这样的作用呢 #看一下字符串的str类的内容里有__len__方法,所