# 一,面向对象的内置函数 class Foo: pass obj=Foo() print(isinstance(obj,Foo)) print(isinstance(Foo,type))# Ture #isinstance()判断是否是对象,第一个参数为对象,第二个为类 # 在python3中统一类与类型的概念 d={'x':1} #d=dict({'x':1}) print(type(d) is dict) print(isinstance(d,dict))#Ture # issubclass() class Parent: pass class Sub(Parent): pass print(issubclass(Sub,Parent))
print(issubclass(Parent,object))#Ture
# 二。反射 # 1、什么是反射 # 通过字符串来操作类或者对象的属性 # # 2、如何用 # hasattr #查看属性是否存在,判断 # getattr #得到属性的值, # setattr #更改属性的值 # delattr #删除属性的值 # 里面参数也就是属性要用字符串 # class People: # country='china' # def __init__(self,name): # self.name=name # def eat(self): # print('%s is eating '%self.name) # peo1=People('egon') # # print(hasattr(peo1,'eat')) # print(hasattr(peo1,'uu'))#False # # print(getattr(peo1,'name'))#得到一个值egon # print(getattr(People,'xou',None))#如果找不到该属性,第三个参数如果写则不报错,并且返回该参数,结果为None # # setattr(peo1,'country','China') #peo1.country='China' # print(peo1.country) # # print(peo1.__dict__) # delattr(peo1,'name')#del peo1.name 删除属性name # print(peo1.__dict__) class Ftp: def __init__(self,ip,port): self.ip=ip self.port=self def get(self): print('GET function') def put(self): print('PUT function') def run(self): while True: choice=input('输入你要操作的命令:').strip() # if hasattr(self,choice): # m=getattr(self,choice,None) # m() m=getattr(self,choice,None)#拿到输入的值,因为是字符串, if m: m() else: print('打印命令不存在')#找到属性则运行,就是反射 obj1=Ftp('11.4..5..6',222) obj1.run()
# 三。内置方法定值类的功能 # 1、__str__ 的方法 class People: def __init__(self,name,age): self.name=name self.age=age #在对象被打印时,自动触发,应该在该方法内采集与对象self有关的信息,然后拼成字符串返回 def __str__(self): return 'name:%s age:%s'%(self.name,self.age) obj1=People('egon',18) obj2=People('alex',19) print(obj1) #obj.__str__() name:egon age:18 print(obj2) #obj.__str__() name:alex age:19 d={'x':1} #d=dict({'x':1}) print(d) #对象和d一样可以直接的打印 # 2.__del__ 析构方法 # # __del__会在对象被删除之前自动触发 class People: def __init__(self,name,age): self.name=name self.age=age self.f=open('a.txt','rt',encoding='utf-8') def __del__(self): self.f.close() #做回收系统资源相关的事情 obj=People('egon',18) print('打印') # obj在运行完就回收
# 四,元类 ''' 1、什么是元类 在python中一切皆对象,那么我们用class关键字定义的类本身也是一个对象 负责产生该对象的类称之为元类,即元类可以简称为类的类 class Foo: #Foo=元类() pass 2.为何要用元类 元类是负责产生类的,所以我们学习元类或者自定义元类的目的 是为了控制类的产生过程,还可以控制对象的产生过程 3、如何用元类 ''' # 1.储备知识:内置函数exec的用法 # cmd=""" # x=1 # def func(self): # pass # """ # class_dic={} # exec(cmd,{},class_dic) # # print(class_dic) #造出类的名称空间 {'x': 1, 'func': <function func at 0x000000E4D57E1E18>} #2.创建类的方法有两种 # 大前提:如果说类也是对象的话,那么用class关键字去创建类的过程也是一个实例化的过程 # 该实例化的目的是为了得到一个类,调用的是元类 # # 2.1 方式一;用默认的元类type # class People: #People=type(....) # country='china' # def __init__(self,name,age): # self.name=name # self.age=age # # def eat(self): # print('%s is eating '%self.name) # # print(type(People)) # # # 2.1.1 创建类的三要素:类名,基类,类的名称空间 # class_name='People' # class_bases=(object,) # class_dic={} # class_body=""" # country='china' # def __init__(self,name,age): # self.name=name # self.age=age # def eat(self): # print('%s is eating'%self.name) # """ # exec(class_body,{},class_dic) # # print(class_name) # print(class_bases) # print(class_dic) # # # People=type(类名,基类,类的名称空间) # People1=type(class_name,class_bases,class_dic) # print(People1) # obj1=People1('egon',18) # print(People) # obj=People('egon',18) # # obj1.eat() # obj.eat() # # 2.2 方式二:用的自定义的元素 # class Mymeta(type):#只有继承了type的类才能称之为一个元类,否则就是一个普通的自定义类 # def __init__(self,class_name,class_bases,class_dic): # print(self)#现在是People # print(class_name) # print(class_bases) # print(class_dic) # super(Mymeta,self).__init__(class_name,class_bases,class_dic)#重用父类的功能 #分析用class自定义类的运行原理(而非元类的运行原理): # 1、拿到一个字符串格式的类名class_name='People' # 2. 拿到一个类的基类们class_bases=(object,) # 3. 执行类体代码,拿到一个类的名称空间class_dic{....} # 4. 调用People=type(class_name,class_bases,class_dic) # class People(object,metaclass=Mymeta):#People=Mymeta(类名,基类们,类的名称空间) # country='China' # def __init__(self,name,age): # self.name=name # self.age=age # # def eat(self): # print('%s is eating '%self.name) # # # 应用:自定义元类控制类的产生过程,类的产生过程其实就是元类的调用过程 # class Mymeta(type):#只有继承了type类才能称之为一个元类,否则就是一个普通的自定义类 # def __init__(self,class_name,class_bases,class_dic): # if class_dic.get('__doc__') is None or len(class_dic.get('__doc__').strip())==0: # raise TypeError('类的注释不能为空') # if not class_name.istitle(): # raise TypeError('首字母必须为大写') # super(Mymeta,self).__init__(class_name,class_name,class_dic)#重用父类的功能 # # class People(object,metaclass=Mymeta):#People=Mymeta('People',(object,),{..}) # '''这是People类''' # country='china' # def __init__(self,name,age): # self.name=name # self.age=age # # def eat(self): # print('%s is eating '%self.name) # # # 3 储备知识:__call__ # class Foo: # def __call__(self, *args, **kwargs): # print(self) # print(args) # print(kwargs) # obj=Foo() # # # 要想让obj这个对象变成一个可调用的对象,需要在该对象的类中定义一个__call__方法 # # 该方法会在调用对象的时候自动触发 # obj(1,2,3,x=1)#给函数类传值 # 4、自定义元类来控制类的调用的过程,即类的实例化过程 class Mymeta(type): def __call__(self, *args, **kwargs): # print(self)#self是People # print(args) # print(kwargs) # return 123 #1.先造出一个People的空对象 obj=self.__new__(self) # 2.为该空对象初始化独有的属性 # print(args,kwargs) self.__init__(obj,*args,**kwargs) # 3.返回一个初始化对象 return obj class People(object,metaclass=Mymeta): country='China' def __init__(self,name,age): self.name=name self.age=age def eat(self): print('%s is eating'%self.name) def __new__(cls, *args, **kwargs): print(cls) #cls.__new__(cls) 错误 obj=super(People,cls).__new__(cls) return obj #分析:调用People的目的 # 1.先造出一个People的空对象 # 2、为该对空对象初始化独有的属性 obj1=People('egon1',age=18) obj2=People('egon2',age=18) print(obj1) print(obj2) obj=People('egon',age=18) print(obj.__dict__) print(obj.name) obj.eat()