面向对象进阶:反射以及内置方法
Posted eaoo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面向对象进阶:反射以及内置方法相关的知识,希望对你有一定的参考价值。
一、反射
反射:使用字符串数据类型的变量名来获取这个变量的值
input:用户输入的如果是a,那么打印1。如果输入的是b那么就打印2.如果输入name,那么打印alex
文件:从文件中读出的字符串,想转换成变量的名字
网络:将网络传输的字符串转换成变量的名字
1.反射类中的变量:静态属性,类方法
# class Foo: # School = ‘oldboy‘ # Country = ‘China‘ # language = ‘Chinese‘ # @classmethod # def class_method(cls): # print(cls.School) # @staticmethod # def static_method(): # print(Foo.School) # # 反射实现 # while True: # inp = input(‘>>>‘) # if hasattr(Foo,inp): # print(getattr(Foo,inp)) # # getattr(Foo,‘class_method‘)() # getattr(Foo, ‘static_method‘)()
解析getattr方法:
# 解析getattr方法: # getattr(变量名: 命名空间, 字符串:属于一个命名空间内的变量名) # getattr(Foo, ‘School‘) # 相当于Foo.School # print(Foo.class_method) # print(getattr(Foo, ‘class_method‘)) # 地址一样
2.反射模块中的变量
import os # so.rename(‘a‘, ‘b‘) # getattr(os, ‘rename‘)(‘a‘, ‘b‘)
3.反射本文件中的变量
# a = 1 # b = 2 # name = ‘alex‘ # def qqxing(): # print(‘qqxing‘) # # # import sys # print(sys.modules[‘__main__‘]) # 本文件的命名空间 # print(sys.modules[‘__main__‘].a) # print([__name__]) # 变量,内置的变量
# 反射本文件中的变量 结论 # a = 1 # b = 2 # name = ‘alex‘ # def qqxing(): # print(‘qqxing‘) # class Foo:pass # # import sys # print(sys.modules[__name__]) # 反射本文件中的变量 固定的使用这个命名空间 # print(getattr(sys.modules[__name__],‘a‘)) # print(getattr(sys.modules[__name__],‘b‘)) # print(getattr(sys.modules[__name__],‘name‘)) # getattr(sys.modules[__name__],‘qqxing‘)() # print(getattr(sys.modules[__name__],‘Foo‘)) # obj = getattr(sys.modules[__name__],‘Foo‘)() # print(obj)
4.setattr
# class Foo: # Country = ‘China‘ # # def func(): # print(‘qqxing‘) # Foo.School = ‘OLDBOY‘ # setattr(Foo,‘School‘,‘OLDOBY‘) # 接受三个参数 命名空间 ‘变量名’ 变量值 # print(Foo.__dict__) # print(getattr(Foo,‘School‘)) # print(Foo.School) # # # setattr(Foo,‘func‘,func) # 一般没人往空间中添加函数 # print(Foo.__dict__) # print(Foo.func)
5.delattr
# delattr # del Foo.Country # print(Foo.__dict__) # delattr(Foo,‘Country‘) # print(Foo.__dict__)
二、内置方法
定义:不需要程序员定义,本身就存在类中的方法就是内置方法
内置方法的形式:__名字__
名字又称为:双下方法,魔术方法,内置方法
作用:不需要我们主动调用,而是实例化时内部自动调用的。
所有的双下方法,都不需要我们直接区调用,都有另外一种自动触发他的语法。
1.__str__ 和 __repr__
# __str__ __repr__ # class Course: # def __init__(self,name,period,price,teacher): # self.name= name # self.period = period # self.price = price # self.teacher = teacher # # def __str__(self): # return ‘str : %s %s %s %s‘ % (self.name, self.period, self.price, self.teacher) # # def __repr__(self): # return ‘repr : %s %s %s %s‘ % (self.name, self.period, self.price, self.teacher) # course_lst = [] # python = Course(‘python‘,‘6 month‘,29800,‘boss jin‘) # course_lst.append(python) # linux = Course(‘linux‘,‘5 month‘,25800,‘oldboy‘) # course_lst.append(linux) # for id,course in enumerate(course_lst,1): # print(‘%s %s %s %s %s‘%(id,course.name,course.period,course.price,course.teacher)) # print(id,course) # print(‘%s %s‘%(id,course)) # print(str(course)) # print(repr(course)) # print(‘%r‘%course)
区别
__str__ 当你打印一个对象的时候 触发__str__ 当你使用%s格式化的时候 触发__str__ str强转数据类型的时候 触发__str__ __repr__ repr是str的备胎 有__str__的时候执行__str__,没有实现__str__的时候,执行__repr__ repr(obj)内置函数对应的结果是 __repr__的返回值 当你使用%r格式化的时候 触发__repr__
顺序
子类有__str__:Son.str 子类没有__str__:找父类,Foo.str 子类父类都没有__str__:Son.repr 子类父类都没有str,子类有repr:Son.repr 否则:Foo.repr
class Foo: # def __str__(self): # return ‘Foo.str‘ def __repr__(self): return ‘Foo.repr‘ class Son(Foo): pass # def __str__(self): # return ‘Son.str‘ # def __repr__(self): # return ‘Son.repr‘ s1 = Son() print(s1)
以上是关于面向对象进阶:反射以及内置方法的主要内容,如果未能解决你的问题,请参考以下文章
python学习8_1 面向对象(继承多态封装)以及零散概念(组合,property,绑定方法与非绑定方法,反射,内置函数)