面向对象之:元类,反射, 双下方法
Posted fengqiang626
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面向对象之:元类,反射, 双下方法相关的知识,希望对你有一定的参考价值。
[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‘>
print(type(dict)) # <class ‘type‘>
python 中一切皆对象, 类在某种意义上也是一个对象,python中自己定义的类,以及大部分内置类,都是由type元类(构建类)实例化得来的
# type 与 object 的关系.
# print(type(object)) object类是type类的一个实例.
# object类是type类的父类.
print(issubclass(type,object))
2.反射
实例对象 类 本模块 其他模块
hasattr getattr setattr delattr
2.1实例对象:
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‘))
# getattr
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__)
2.2从类的角度:
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)
2.3从其他模块:
import tbjx
print(getattr(tbjx,‘name‘))
getattr(tbjx,‘func‘)()
# 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‘))
# 从当前模块研究反射:
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‘)
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‘funci‘ for i in range(1,5)]
print(func_lst)
for func in func_lst:
getattr(sys.modules[__name__],func)()
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‘)
3.函数与方法的区别
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()
# 总结: 如何判断类中的是方法还是函数.
# 函数都是显性传参,方法都是隐性传参.
4.特殊双下方法
特殊的双下方法: 原本是开发python这个语言的程序员用的.源码中使用的. str : 我们不能轻易使用.慎用. 双下方法: 你不知道你干了什么就触发某个双下方法.
4.1__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))
4.2__len__
class A(object):
pass
obj = A()
print(hash(obj))
print(hash(‘fdsaf‘))
4.3__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))
4.4__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))
4.5__call__
__call__方法 ***
对象() 自动触发对象从属于类(父类)的__call__方法
class Foo:
def __init__(self):
pass
def __call__(self, *args, **kwargs):
print(‘__call__‘)
obj = Foo()
obj()
4.6__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)
4.7__del__
__del__析构方法
class A:
def __del__(self):
print(666)
obj = A()
del obj
4.8__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)
以上是关于面向对象之:元类,反射, 双下方法的主要内容,如果未能解决你的问题,请参考以下文章
python 面向对象专题:元类type反射函数与类的区别特殊的双下方法