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

落花浮王杯 提交于 2020-02-26 23:11:34

day26

type元类与object联系

type 获取对象从属于的类

python 中一切皆对象, 类在某种意义上也是一个对象,python中自己定义的类,以及大部分内置类,都是由type元类(构建类)实例化得来的.

obj = A()
print(type('abc'))
print(type([1,2,3]))
print(type((22,33)))

# type 获取对象从属于的类
print(type(A))
print(type(str))
print(type(dict))
type 与 object 的关系.
  • object类是type类的一个实例
print(type(object)) 
  • object类是type类的父类.
print(issubclass(type,object))

反射

程序对自己内部代码的一种自省方式.

反射是什么? 通过字符串去操作对象的方式.

实例对象
# class A:
#
#     country = '中国'
#
#     def __init__(self,name,age):
#         self.name = name
#         self.age = age
#
#     def func(self):
#         print('in A func')

# obj = A('赵海狗',47)

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

# print(getattr(obj,'name'))
# print(getattr(obj,'func'))
# f = getattr(obj,'func')
# f()
# print(getattr(obj,'sex',None))
# if hasattr(obj,'name'):
#     getattr(obj,'name')

# setattr,delattr 用的很少
# obj.sex = '公'
# print(obj.sex)
# setattr(obj,'sex','公')
# print(obj.__dict__)
# delattr(obj,'name')
# print(obj.__dict__)
类的角度
# 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')()
#     getattr(A,'func')(obj)
本模块
# 从当前模块研究反射:
# a = 666
#
# def func1():
#     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()
# # l1 = [func1,func2,func3,func4,]
# import sys
# # # print(sys.modules[__name__])
# # print(getattr(sys.modules[__name__],'a'))
# # getattr(sys.modules[__name__],'func1')()
# # getattr(sys.modules[__name__],'func2')()
# # getattr(sys.modules[__name__],'func3')()
#
# func_lst = [f'func{i}' for i in range(1,5)]
# # print(func_lst)
# for func in func_lst:
#     getattr(sys.modules[__name__],func)()


# 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)


# 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()  # 1
#     obj = User()
#     getattr(obj, obj.user_list[int(choose)-1][0])()  # getattr(obj,'login')

其他模块
-----------------------------------
name = '太白金星'

def func():
    print('in tbjx func')



class C:
    area = '北京'

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

    def func(self):
        print('in B func')
-----------------------------------
# import tbjx
# print(getattr(tbjx,'name'))
# getattr(tbjx,'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'))

函数与方法的区别

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

def func1():
    pass

class A:
    def func(self):
        pass

# 1. 通过打印函数名的方式区别什么是方法,什么是函数. (了解)
# print(func1)
# print(A.func)  # 通过类名调用的类中的实例方法叫做函数.
# obj = A()
# print(obj.func) # 通过对象调用的类中的实例方法叫方法.

# 2 可以借助模块判断是方法还是函数.

# 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()

# 总结: 如何判断类中的是方法还是函数.
# 函数都是显性传参,方法都是隐性传参.

特殊的双下方法

必考,对源码的研究,以后的开发

特殊的双下方法: 原本是开发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__)  # 2
#
# b = B('leye',28)
#
# print(len(b))

# dict
# print(len({'name': 'leye', 'age': 28}))
______hash______
# class A(object):
#
#     pass
#
# obj = A()

# print(hash(obj))
# str
# print(hash('fdsaf'))
______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('李业',56)
# c = A('华丽',18)
# 打印对象触发__str__方法
# print(f'{a.name}  {a.age}')
# print(f'{b.name}  {b.age}')
# print(f'{c.name}  {c.age}')
# print(a)
# print(b)
# print(c)
# 直接str转化也可以触发.
# print(str(a))
______repr______
# print('我叫%s' % ('alex'))
# print('我叫%r' % ('alex'))
# print(repr('fdsaf'))


# 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('李业',56)
# c = A('华丽',18)
# # print(a)
# print(repr(a))


# class A:
#
#     def __init__(self,name,age):
#         self.name = name
#         self.age =age
#
#     def __str__(self):
#         return '777'
#
#
#     def __repr__(self):
#         return '666'
#
# a = A('赵海狗',35)
# b = A('李业',56)
# c = A('华丽',18)
# # print(a)
# print(a)
______call______
***
# 对象() 自动触发对象从属于类(父类)的__call__方法
# class Foo:
#
#     def __init__(self):
#         pass
#
#     def __call__(self, *args, **kwargs):
#         print('__call__')
#
# obj = Foo()
# obj()
______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)
# x = 1
# y = 2
# print(x+y)
______del______
# __del__析构方法

# class A:
#
#     def __del__(self):
#         print(666)
#
# obj = A()
# del obj
______new______
# __new__ *** 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()

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

# print(a)

# python中的设计模式: 单例模式

# 一个类只允许实例化一个对象.
# class A:
#
#     pass
# obj = A()
# print(obj)
# obj1 = A()
# print(obj1)
# obj2 = A()
# print(obj2)

# 手写单例模式
# 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)
______item______系列

______getitem______、______setitem______、______delitem______ 对对象做类似于字典的(增删改查)触发______item______系列

______delattr______ del obj.属性 ,机会触发此方法

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]时,我执行")

    def __delattr__(self, item):
        super().__delattr__(item)
        print(f"对象的{item}属性已经删除")


f1 = Foo("sb")
# print(f1["name"])
# print(f1["age"])
# f1[1] = 2
# del f1[1]

# del f1.name
# print(f1.__dict__)
______enter______ 或______exit______

______enter______ 或______exit______ with 上下文管理

  • 实例化的对象的第二种方式
class A:
    def __init__(self, name):
        self.name = name

    def __enter__(self):
        print(666)

    def __exit__(self, exc_type, exc_val, exc_tb):
        print(777)


# obj = A("海狗")
# 实例化对象的第二种方式:必须基于 __enter__ 以及 __exit__ 这两个方法
with A("海狗") as obj:
    print(obj.name)
  • 执行顺序
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)  # 第四步
______iter______
class A:
    def __init__(self, name):
        self.name = name

    def __iter__(self):
        for i in range(10):
            yield i

    def __next__(self):
        pass


obj = A("李业")  # obj 一个可迭代对象
# print("__iter__" in dir(obj))
# for i in obj:
#     print(i)

print(obj.name)
o = iter(obj)   # 迭代器
print(next(o))
print(next(o))
print(next(o))
print(next(o))
print(next(o))
print(next(o))
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!