python, nineteen day

反射

是什么

反射,使用字符串数据类型的变量名来获取这个变量的值

why 为什么 三个场景

a = 1
b = 2
name = ‘xiao’
View Code
1.input:用户输入的如果是a,那么就打印1,如果输入的是b就打印2,如果输入的是name,就打印xiao
2.文件:从文件中读出的字符串,想转换成变量的名字
3.网络:将网络传输的字符串转化成变量的名字

where 在哪儿用

class Foo:
    School = 'oldboy'
    Country = 'China'
    language = 'Chiness'

    @classmethod
    def class_method(cls):
        print(cls.School)
    @staticmethod
    def static_method():
        print('in staticmethod')

    def wahaha(self):
        print('wahaha')
print(Foo.School)
print(Foo.Country)
print(Foo.language)
# 反射实现
while True:
    inp = input('>>>')
    if hasattr(Foo,inp):            #判断是否在类中
        print(getattr(Foo,inp))
    
getattr(Foo,'School')  # Foo.School
print(Foo.class_method)
print(getattr(Foo,'class_method'))
getattr(Foo,'class_method')()    # Foo.class_method()
getattr(Foo,'static_method')()   # Foo.static_method()
getattr(Foo,'wahaha')(1)  # Foo.wahaha(1)
print(hasattr(Foo,'wahaha'))
print(hasattr(Foo,'shuangwaiwai'))
View Code

hasattr方法

hasattr 判断

getattr方法

getattr(变量名:命名空间,字符串:属于一个命名空间内的变量名)

反射模块中的变量

import os
getattr(os,'rename')('娃哈哈','爽歪歪')  #os.rename('娃哈哈','爽歪歪')
View Code

反射本文件中的变量

a = 1
b = 2
name = 'vip'
def thank():
    print('thank')
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__],'thank')()
print(getattr(sys.modules[__name__],'Foo'))     #<class '__main__.Foo'>
obj = getattr(sys.modules[__name__],'Foo')()    #<__main__.Foo object at 0x0000021CC9037668>
print(obj)
View Code

setattr

class Foo:
    country = 'China'
def func();
    print('think')
setattr(Foo,'School','study')   #Foo.School = 'study' # 接受三个参数 命名空间 ‘变量名’ 变量值
print(Foo.__dict__)
print(getattr(Foo,'School'))
print(Foo.School)

setattr(Foo,'func',func)  # 一般没人往空间中添加函数
print(Foo.__dict__)
print(Foo.func)
View Code

内置方法

在不是需要程序员定义,本身就存在在类中的方法就是内置方法。
内置方法通常长这样: __ 名字__
名字: 双下方法、魔术方法、内置方法

__ init__

不需要我们主动调用,而是在实例化的时候内部自动调用的
所有的双下方法,都不需要我们直接去调用,都有另外一种自动触发它的语法

__ str __ __ repr__

__ str__
1.当你打印一个对象的时候,触发__ str__
2.当你使用%s格式化的时候,触发 __ str__
3.str强转数据类型的时候,触发 __ str__
__ repr__
1.repr是str的备胎
2.有__str__的时候执行__str__,没有实现__str__的时候,执行__repr__
3.repr(obj)内置函数对应的结果是__repr__的返回值
4.当你使用%r格式化 时候 触发__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)
View Code
父类与子类 __ str__ __ 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)
View Code

总结:先__str__,如果没有去父类找__str__,还没有就找子类的__repr__,最后没有就找父类的__repr__。

猜你喜欢

转载自www.cnblogs.com/study-learning/p/9567533.html