python_面向对象-反射与常用内置方法

一、反射

  1、反射是什么?

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

  2、常用几个场景?

    input

      根据用户的输入,获取相应的值

    文件

      从文件读出的字符串,想转成变量的名字

    网络

      将网络传输的字符串转成变量的名字

  3、getattr 与 hasattr

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

# 反射类中的静态属性,类方法,静态方法
class Foo:
    School = '希望小学'
    country = 'china'

    @classmethod
    def class_method(cls):
        print(cls.School)

    def static_method():
        print('is static')

while 1:
    inp = input('<<<').strip()
    print(getattr(Foo,inp))
View Code
# 反射对象中的变量,普通方法,对象属性
class Foo:
    def __init__(self,name,age):
        self.name = name
        self.age = age

    def eat(self):
        print('吃东西')

f = Foo('xiaoming',12)
print(getattr(f,'name'))
print(getattr(f,'age'))
getattr(f,'eat')()
View Code
# 反射本文件中的变量
a = 1
def fun():
    print('xxx')
class Foo:pass
import sys
# print(sys.modules['__main__'])  #获取本文件的命名空间  F:/Demo/面向对象/反射与内置方法.py
# print(sys.modules['__main__'].a)
# print(__name__)

print(getattr(sys.modules[__name__],'a'))
print(getattr(sys.modules[__name__],'fun')())
obj = getattr(sys.modules[__name__],'Foo')()
print(obj)
View Code

   4、setattr 与      delattr

class Foo:
    country = 'china'

def fun():
    print('xxx')

setattr(Foo,'country','us')  #接收三个参数 命名空间 变量名 变量值
print(Foo.__dict__)
print(getattr(Foo,'country'))
print(Foo.country)

setattr(Foo,'fun',fun)
print(Foo.__dict__)
getattr(Foo,'fun')()  #一般不往空间中添加函数

delattr(Foo,'country')
print(Foo.__dict__)
View Code

 

二、内置方法

  1、不需要自己定义,本身就存在类中的方法

     一般都是__变量名__,又叫双下方法,魔术方法

  2、__str__  __repr__

class Course:
    def __init__(self,name,price,teacher):
        self.name = name
        self.price = price
        self.teacher = teacher

    def __str__(self):
        return 'str: %s %s %s' %(self.name,self.price,self.teacher)

    def __repr__(self):
        return 'repr: %s %s %s' % (self.name, self.price, self.teacher)

course_list = []
python = Course('python',29800,'jing-l')
linux = Course('linux',9800,'taix)

course_list.append(python)
course_list.append(linux)

for id,course in enumerate(course_list,1):
    print(id,course)
    print('%s %s' %(id,course))
    print(id,str(course))

    print(id,repr(course))
    print('%s %r' %(id,course))
# __str__
# 当你打印一个对象的时候  触发__str__
# 当你使用%s格式化的时候  触发__str__
# str强转数据类型的时候   触发__str__

# __repr__
# repr是str的备胎
# 有__str__的时候执行__str__,没有实现__str__的时候,执行__repr__
# repr(obj)内置函数对应的结果是 __repr__的返回值
# 当你使用%r格式化的时候 触发__repr__
View Code

    3、__new__

# 在init之前实例化对象的第一步是__new__创建了一个空间
# 单例模式
class Foo:
    __instance = None
    def __init__(self,name):
        self.name = name

    def __new__(cls, *args, **kwargs):
        if cls.__instance is None:
            cls.__instance = object.__new__(cls)
        return cls.__instance

f1 = Foo('alex')
f2 = Foo('zs')
View Code

    4、__del__

class Foo:
    def __init__(self,name):
        self.name = name
        self.file = open('file.txt','w')

    def write(self):
        self.file.write('aaa')

    def __del__(self):    # 析构方法 : 在删除这个类创建的对象的时候会先触发这个方法,再删除对象
         # 做一些清理工作,比如说关闭文件,关闭网络的链接,数据库的链接
        self.file.close()
        print('执行del了')

f = Foo('zs')
print(f)
View Code

   5、__len__

class Foo:
    def __init__(self,name):
        self.name = name
        self.students = []

    def __len__(self):
        return len(self.students)

s1 = Foo('无极限')
s1.students.append('zs')
s1.students.append('lisi')
s1.students.append('xm')
print(len(s1))
View Code

   6、__eq__

class Staff:
    def __init__(self,name,sex):
        self.name = name
        self.sex = sex

    def __eq__(self, other):
        # 原本是比较id内存地址
        return self.__dict__ == other.__dict__

s1 = Staff('asf','male')
s2 = Staff('asf','male')
s3 = Staff('asf','fmale')
print(s1 == s2)
print(s3 == s2)
View Code

   7、__hash__  

  set 的去重机制
1.对每一个元素进行hash计算出一个内存地址
2.到这个内存地址上查看
如果这块内存中没有值
将这个元素存到对应的内存地址上
如果这块内存中已经有值
判断这两个值是否相等
如果相等 就舍弃后面的值
如果不相等 就二次寻址再找一个新的空间来存储这个值
# 1.对于相同的值在一次程序的运行中是不会变化的
# 2.对于不同的值在一次程序的运行中总是不同的
class Staff:
    def __init__(self,name,age,sex,dep):
        self.name = name
        self.age = age
        self.sex = sex
        self.dep = dep
    def __hash__(self):
        return hash(self.name + self.sex)
    def __eq__(self, other):
        if self.name == other.name and self.sex == other.sex:
            return True

name_lst = ['yuan','egon','nazha','peiqi']
obj_lst = []
for i in range(100):
    name = name_lst[i%4]
    obj = Staff(name,i,'male','python')
    obj_lst.append(obj)
print(len(obj_lst))
ret = set(obj_lst)
print(ret)
for i in ret:
    print(i.name,i.age)
View Code

 

posted on 2018-08-31 20:35  旧巷子里的猫  阅读(150)  评论(0编辑  收藏  举报