反射 魔法方法 单例模式

反射

反射:指的是通过“字符串”对 对象或类的属性进行操作

​ hasattr:通过对字符串,判断该字符串是否是对象或类的属性

​ getattr:通过字符串,获取对象或类的属性

​ setattr:通过字符串,设置对象或类的属性

​ delattr:通过字符串,删除对象或类的属性

class People:
    country='China'

    def __init__(self,name,age,sex):
        self.name=name
        self.age=age
        self.sex=sex

#hasattr
p=People('tank',18,'male')
print(hasattr(p,'name'))#True
print(hasattr(People,'country'))#True

#getattr
print(getattr(p,'name','nick'))#tank
print(getattr(p,'name1','nick'))#nick
print(getattr(People,'country','China'))#China

#setattr
setattr(p,'sal','3.0')
print(hasattr(p,'sal'))#Ture
print(p.sal)#3.0
setattr(People,'Sal','3.0')
print(hasattr(People,'Sal'))#Ture
print(People.Sal)#3.0

#delattr
delattr(p,'sal')
print(hasattr(p,'sal'))#False
delattr(People,'Sal')
print(hasattr(People,'Sal'))#False
class Movie:
    def input_cmd(self):
        print('输入命令:')
        while True:
            cmd=input('请输入执行的方法名').strip()
            #若用户输入的cmd命令是当前对象的属性
            if hasattr(self,cmd):
                method=getattr(self,cmd)
                method()
            else:
                print('命令错误,请重新输入')

    def upload(self):
        print('电影开始上传。。。')

    def download(self):
        print('电影开始下载。。。')

movie_obj=Movie()
movie_obj.input_cmd()
'''输入命令:
请输入执行的方法名upload
电影开始上传。。。
请输入执行的方法名download
电影开始下载。。。
请输入执行的方法名'''

魔法方法(类的内置方法)

​ 凡是在类内部定义,以__开头__结尾的方法都称为魔法方法,又称类的内置方法。

__init__:在调用类时触发
__str__:会在打印对像时触发
__del__:对象被销毁前执行该方法,该方法会在最后执行
__getattr__:会在对象.属性时,“属性没有”的情况下才会触发。(有__getattributr__就不会触发__getattr__)
__setattr__:会在“对象.属性=属性值”时书法
__call__:会在对象被调用时触发
__new__:会在__init__之前前触发
__getattributr__:会在对象.属性时,属性不管有没有都会触发。
__delatttr__:会在对象删除属性时触发
class Foo(object):
    def __new__(cls, *args, **kwargs):
        print(cls)
        return object.__new__(cls)#真正产生一个空对象

     #若当前类的__new__没有return一个空对象时,__init__不会触发
    def __init__(self):
        print('__init__在调用类时触发')

    def __str__(self):
        print('__str__会在打印对象时触发')
        #必须要有一个返回值,该返回值必须是字符串类型
        return '__str__必须要有一个返回值,该返回值必须是字符串类型'

    def __del__(self):
        print('__del__对象被注销前执行该方法')

    def __getattr__(self, item):
        print('__getattr__会在对象.属性时,"属性没有"的情况下才会触发')
        print(item)
        #默认返回None,若想打印属性的结果,必须return一个值
        return 111

    #注意:执行该方法时,外部“对象.属性=属性值”是无效的
    def __setattr__(self, key, value):
        print('__setattr__会在“对象.属性=属性值”时触发')
        print(key,value)

    def __call__(self, *args, **kwargs):
        print('__call__调用对象时触发该文件')


foo_obj=Foo()
print(foo_obj)
foo_obj.x
foo_obj.y=10
foo_obj()
'''<class '__main__.Foo'>
__init__在调用类时触发
__str__会在打印对象时触发
__str__必须要有一个返回值,该返回值必须是字符串类型
__getattr__会在对象.属性时,"属性没有"的情况下才会触发
x
__setattr__会在“对象.属性=属性值”时触发
y 10
__call__调用对象时触发该文件
__del__对象被注销前执行该方法'''

单例模式

​ 单例模式指的是单个实例,实例指的是调用类产生的对象

​ 实例化多个对象会产生不同的内存地址,单例可以让所有调用者在调用类产生对象的情况下都指向一份内存地址。

目的:

​ 为了减少内存的占用

class File:
    __instance=None

    # @classmethod
    # def singleton(cls,file_name):
    #     if not cls.__instance:
    #         obj=cls(file_name)
    #         cls.__instance=obj
    #     return cls.__instance

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

    def __init__(self, file_name, mode='r', encoding='utf-8'):
        self.file_name = file_name
        self.mode = mode
        self.encoding = encoding

    def open(self):
        self.f = open(self.file_name, self.mode, encoding=self.encoding)

    def read(self):
        res = self.f.read()
        print(res)

    def close(self):
        self.f.close()

# obj1=File.singleton('mofa.py')
# obj2=File.singleton('mofa.py')
# print(obj1)
# print(obj2)

obj1=File('mofa.py')
obj2=File('mofa.py')
print(obj1)
print(obj2)
posted @ 2020-03-29 13:05  风啊风啊  阅读(147)  评论(0编辑  收藏  举报