day22-类的绑定方法和非绑定方法、反射、魔法方法、单例模式

类的绑定方法和非绑定方法

类的绑定方法

import hashlib
import uuid
import settings
class Teacher:
    def __init__(self, user, pwd):
        self.user = user
        self.pwd = pwd

    # 主页
    def index(self):
        if self.user == 'tank' and self.pwd == '123':
            print('验证通过,显示主页...')
            
	'''
	类中使用 @classmethod 修饰的方法就是绑定到类的方法。这类方法专门为类定制。
	通过类名调用绑定到类的方法时,会将类本身当做参数传给类方法的第一个参数。
	'''
    @classmethod
    def login_auth_from_settings(cls):
        obj = cls(settings.USER, settings.PWD)
        return obj  # Teacher() ---> return = obj

类的非绑定方法

staticmethod是一个装饰器,可以装饰给类内部的方法,使该方法即不绑定给对象,也不绑定给类

@staticmethod
def create_id():
    # 生成一个唯一的id字符串
    uuid_obj = uuid.uuid4()
    md5 = hashlib.md5()
    md5.update(str(uuid_obj).encode('utf-8'))
    return md5.hexdigest()

isinstance和issubclass

isinstance

#判断对象是否是class的一个实例
isinstance(obj, class)

issubclass

#判断cls1是否是cls2的子类
issubclass(cls1, cls2)

反射

反射就是通过字符串来操作类或者对象的属性

反射本质就是在使用内置函数,其中反射有以下四个内置函数

  1. hasattr:判断一个方法是否存在与这个类中
  2. getattr:根据字符串去获取obj对象里的对应的方法的内存地址,加"()"括号即可执行
  3. setattr:通过setattr将外部的一个函数绑定到实例中
  4. delattr:删除一个实例或者类中的方法
class People:
    country = 'China'

    def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex
# hasattr
print(hasattr(p, 'name'))  # True
print(hasattr(People, 'country'))  # True
#getattr
print(getattr(p, 'name', 'jason_sb'))  # tank
print(getattr(p, 'name1', 'jason_sb'))  # jason_sb
print(getattr(People, 'country2', 'China'))
# setattr
setattr(p, 'sal', '3.0')
print(hasattr(p, 'sal'))  # True
# delattr
delattr(p, 'sal')
print(hasattr(p, 'sal'))  # False

魔法方法(内置方法)

__init____new__

__new__方法的第一个参数是这个类,而其余的参数会在调用成功后全部传递给__init__方法初始化

__new__方法是传入类(cls),而__init__方法传入类的实例化对象(self),而有意思的是,__new__方法返回的值就是一个实例化对象(ps:如果__new__方法返回None,则__init__方法不会被执行,并且返回值只能调用父类中的__new__方法,而不能调用毫无关系的类的__new__方法)。

class A:
    pass


class B(A):
    def __new__(cls):
        print("__new__方法被执行")
        return super().__new__(cls)

    def __init__(self):
        print("__init__方法被执行")
b = B()
__new__方法被执行
__init__方法被执行

__str__

打印对象时触发

__del__

对象被销毁前执行该方法,该方法会在最后执行(如果程序中间通过del删除对象也会执行)

__getattr__

会在对象.属性时,“属性没有”的情况下才会触发

__setattr__

会在 “对象.属性 = 属性值” 时触发

__call__

会在对象被调用时触发

class Foo(object):

    def __new__(cls, *args, **kwargs):
        print(cls)
        return object.__new__(cls)  # 真正产生一个空对象

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

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

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

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

    # 注意: 执行该方法时,外部“对象.属性=属性值”时无效。
    def __setattr__(self, key, value):
        print('会在 “对象.属性 = 属性值” 时触发...')
        print(key, value)
        print(type(self))
        print(self, 111)
        self.__dict__[key] = value  #当存在__setattr__方法时,只能通过这种方式修改值

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

foo_obj = Foo()
print(foo_obj)
print(foo_obj.x)
print(foo_obj.x)
foo_obj.x = 123
print(foo_obj.x)
foo_obj()
list1 = [1, 2, 3]  # list1 = list([1, 2, 3])
print(list1)  # [1, 2, 3]
<class '__main__.Foo'>
在调用类时触发...
<__main__.Foo object at 0x000001F5AFFBBE10>
会在对象.属性时,“属性没有”的情况下才会触发...
x
111
会在对象.属性时,“属性没有”的情况下才会触发...
x
111
会在 “对象.属性 = 属性值” 时触发...
x 123
<class '__main__.Foo'>
<__main__.Foo object at 0x000001F5AFFBBE10> 111
123
<__main__.Foo object at 0x000001F5AFFBBE10>
调用对象时触发该方法...
[1, 2, 3]
对象被销毁前执行该方法...

单例模式

从配置文件中获取相同的文件名

class File:

    __instance = None

    # 单例方式1:
    @classmethod
    def singleton(cls, file_name):
        if not cls.__instance:
            obj = cls(file_name)
            cls.__instance = obj
        return cls.__instance
#方式1:
obj1 = File.singleton('jason雨后的小故事.txt')  # singleton(cls)
obj2 = File.singleton('jason雨后的小故事.txt')  # singleton(cls)
obj3 = File.singleton('jason雨后的小故事.txt')  # singleton(cls)
# obj1 = File('jason雨后的小故事.txt')
# obj2 = File('jason雨后的小故事.txt')
# obj3 = File('jason雨后的小故事.txt')
print(obj1)
print(obj2)
print(obj3)
    
class File:

    __instance = None
    
    # 单例方式2:
    def __new__(cls, *args, **kwargs):
        # cls.__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()

# 方式2:
obj1 = File('jason雨后的小故事.txt')  # singleton(cls)
obj2 = File('jason雨后的小故事.txt')  # singleton(cls)
obj3 = File('jason雨后的小故事.txt')  # singleton(cls)
print(obj1)
print(obj2)
print(obj3)
    

posted on 2019-10-12 18:44  shenblogs  阅读(127)  评论(0)    收藏  举报

导航