new方法、定制属性访问、描述符与装饰器知识点总结

new,方法,定制,属性,访问,描述符,装饰,知识点,总结 · 浏览次数 : 1

小编点评

**1. id(a) 和 id(a2) 的区别:** `id(a)` 返回对象的唯一标识符,而 `id(a2)` 返回的对象本身。 **2. 如何判断一个实例里面有某个属性呢?** 可以使用 `hasattr()` 方法。该方法的参数是属性名称,第二个参数是实例。如果该方法返回 True,则说明实例中存在该属性。 **3. 怎样删除实例属性呢?** 可以使用 `setattr()` 方法删除属性。该方法的参数是属性名称,第三个参数是属性值。如果该方法返回 True,则说明属性已删除。 **4. 怎样删除变量呢?** 可以使用 `delattr()` 方法删除属性。该方法的参数是属性名称,第二个参数是实例。如果该方法返回 True,则说明属性已删除。 **5. 如何判断是否存在属性,如果属性存在则进行下一步操作?** 可以使用 `getattr()` 方法。该方法的参数是属性名称,第二个参数是实例。如果该方法返回非空,则说明属性存在。 **6. 描述符(比较抽象的一个概念,了解即可)** 描述符是类中实例化另一个类的属性。当在一个类中实例化另一个类,对这个属性进行访问的时候,需要使用 `__getattr__()` 方法。 **7. Decorator 的作用(本质是函数,能够实现在不改变原来的函数的基础上添加功能)** 装饰器是函数,可以用于在函数上添加新的功能。当使用装饰器时,需要将装饰器与要装饰的函数一起定义。 **8. 通过参数aa接受===>f2aa=f1(f3) # 执行f1 把f3当做一个参数传进去#aa() # 输出顺:序这里是f3 这里是f2运行截图:** 通过参数传递,可以将一个方法调用到另一个方法中。 **9. Python也有自带的装饰器(以下python自带的三个内置装饰器)** `@property`:创建一个属性。 `@staticmethod`:创建一个静态方法。 `@classmethod`:创建一个类方法。

正文

第一部分:__new__方法

思考:

  a. 我们创建实例是通过什么方法创建的呢?

  b. 类每次实例化的时候都会创建一个新的对象,如果要求类只能被实例化一次该怎么做呢?===通过单利模式实现  

        c.什么是单例模式(Singleton Pattern )

  1、确保一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,单例模式是一种对象创建型模式


 2、是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场

 3、如果instance是None,则创建对象并赋值给instance,如果instance等于之前创建的对象,则直接返回

例1:创建单例典范(保证只有一个对象,只执行一次init方法)
     问题:
类每次实例化的时候都会创建一个新的对象,如果要求类只能被实例化一次该怎么做呢?
a:用__new__方法实现单例模式可以当成一个范式记忆
b:节省空间
c:new 方法在实例化的时候最先被执行

步骤:
# 单例模式思路:
# 需要生成一个实例===》通过一个方法创建的===》通过object中的__new__方法生成的实例===>返回地址空间
# 以下写法a与a2就不再是独立的实例
# 每次实例的时候都会开辟一个新的空间
# a=A() # 通过object中的__new__方法生成的实例
# a2=A()

# 需求:这个类只能够我一个人使用怎么办?(这个实例实例化了就不能够再创建实例了)
# 只让__new__创建一个实例,重写====》加个条件===》super
# 条件:第一次实例的时候、保存第一次创建的实例 (创建并保存)
# 不是第一次实例的时候:返回第一次创建的实例地址

class A(object):
    instance = None  # 这个属性要在方法外面
    
    #def __init__(self): # 这个方法可以不写,直接写属性就行
      
      #  name='aa'
    # cls==》当前类 A
    # 初始化在__new__方法之后
    def __new__(cls, *args, **kwargs): # 重写object类中的new方法

        # hasattr(cls,'instance')为True,加个not就是False语句
        # if not hasattr(cls,'instance'):  #  instance是一个随便写的属性
        if not cls.instance:
            # 创建一个实例并把实例地址空间保存到cls.instance中
            cls.instance=super().__new__(cls)  # new方法来自与object类
            # A.instance = super().__new__(A)  # cls==A
        # else:
        # 不满足就返回
        return cls.instance  # cls.instance为第一次创建的地址空间

a=A()
a.name='小米'  # 初始化,如果这行代码注释的话就没有初始化实例
print(a.name)
# 当第二次创建实例直接返回地址空间==》cls.instance
a2=A()
print(a2.name)
print(id(a))
print(id(a2))

运行截图:

延伸1.:hasattr 方法

class A(object):
    name='小明'

a=A()
# hasattr这个方法是查找有没有这个属性返回bool值,前面放得是类名或者实例,后面是属性变量
print(hasattr(a,'name')) # True
print(hasattr(a,'name1')) # False

运行截图:

 

 延伸2:初始化的重要性

class A(object):
    instance = None  # 这个属性要在方法外面
    name='aa'

    # 初始化在__new__方法之后
    def __new__(cls, *args, **kwargs): # 重写object类中的new方法

        # hasattr(cls,'instance')为True,加个not就是False语句
        # if not hasattr(cls,'instance'):  #  instance是一个随便写的属性
        if not cls.instance:
            # 创建一个实例并把实例地址空间保存到cls.instance中
            cls.instance=super().__new__(cls)  # new方法来自与object类
            # A.instance = super().__new__(A)  # cls==A
        # else:
        # 不满足就返回
        return cls.instance  # cls.instance为第一次创建的地址空间

a=A()
# a.name='小米'  # 如果注释的话这里代表实例没有初始化
print(a.name)
print(a.__dict__) # 如果没有初始化空值
# 当第二次创建实例直接返回地址空间==》cls.instance
a2=A()
print(a2.name)
print(a2.__dict__)
print(id(a))
print(id(a2))

 运行截图:

 

第二部分:定制属性访问

思考:

    a. 如何判断一个实例里面有某个属性呢?

    b. 怎样删除实例属性呢?

    c. 同样的怎样删除变量呢?

 例1:

# 定制属性访问
class A(object):
    pass
  
    def __getattr__(self, item):

        return '写错了'

a=A()
a.name='小明'  # 增加或者修改
print(a.name)  # 查找==》内容
print(hasattr(a,'name'))  # 查找==》返回的是bool类型
# print(hasattr(a,'name22'))  # False  # 判断是否存在属性,如果属性存在则进行下一步操作
print(getattr(a,'name'))  # 小明
# print(getattr(a,'name2')) # AttributeError: 'A' object has no attribute 'name2'
print(getattr(a,'name2','222'))  # 222为默认值 调用__getattr__
print(a.__getattribute__('name')) # 小明
# AttributeError: 'A' object has no attribute 'name2'
# print(a.__getattribute__('name2')) # 小明

a.name='小满哥'  # 修改
print(a.name)

# 修改跟添加一样,有则改无则增加
setattr(a,'name','xiaoxiao')  #  修改 (实例、属性、属性值)
setattr(a,'name2','xiaofei')  #  添加 (实例、属性、属性值)
print(a.name)  # xiaoxiao
print(a.name2) # xiaofei
a.__setattr__('name3','xiaohua') # 修改
print(a.name3)
# 删除
# delattr(a,'name')
# a.__delattr__('name')
# print(a.name)
# del a  # 删除实例

运行截图:

 第三部分:描述符(比较抽象的一个概念,了解即可

 

      一个类中如果实现了__get__、__set__、__delete__中某一个方法就称为描述符

 

思考:

          如果在一个类中实例化另一个类,对这个属性进行访问的时候怎么做的?

class A:
    # 当这个类在另一个类中当做属性的时候并访问这个属性被调用
    # 如果把这个get方法注释不写输出<__main__.A object at 0x000001F28B996080>
    def __get__(self, instance, owner):
        return 'get'
    # 在修改的时候调用
    def __set__(self, instance, value):
        print('set')

    # 在删除的时候调用
    def __delete__(self, instance):
        print('del')

class B:
    name='aa'
    a=A()  # 1.实例化  2.把a当做属性

b=B()
# 查
print(b.a) # a为属性,可以访问  输出 get  实际调用的是get魔术方法
print(b.name) #
# 修改
b.a=123
# 删除
del b.a

运行截图:

第四部分:装饰器(本质是函数,能够实现在不修改原来的函数的基础上添加功能 

              1. 回顾知识点:

      闭包:外层函数返回内层函数

def f1(obj):  # obj就代表是f3
    print('这里是f1')
    print(obj)
    # 以下f2()函数代码只有被调用才执行
    def f2():
        obj()  # 调用f3
        print('这里是f2')
    return f2

def f3():
    print('这里是f3')
#
# 通过参数aa接受===>f2
aa=f1(f3)  # 执行f1  把f3当做一个参数传进去
#
aa() # 输出顺:序这里是f3   这里是f2

运行截图: 

 2.  装饰器的作用(在不改变别人代码的同时添加新的功能)

# 以下为自己写的装饰器
def f1(obj):  # obj就代表是f3
    print('这里是f1')     # 添加格外的功能

    def f2():
        obj()  # 调用f3
        print('这里是f2')
    return f2

@f1   # 这个相当与以上===》f1(f3) 即调用f1
def f3():  # 把f3当做是别人已经写好的方法
    print('这里是f3')

f3()  # 执行f3  ====》a()   实际就是在调用f2函数

运行截图:

 3. Python也有自带的装饰器(以下python自带的三个内置装饰器)

class A:
    @property  # 这个装饰器的作用:就像访问属性一样访问方法
    def area(self):
        print('这里是area方法')
    @staticmethod  #
    def func():
        print('这里是func方法')
    @classmethod  # 把第一个参数变成类本身
    # def show(self):
    #     print(self)
    #     print('这里是show函数')】
    # 改为以下写法
    def show(cls):
        print(cls)
        print('这里是show函数')

a=A()
a.area
a.func()  # 无需传参 可以用类调用
A.func()
a.show()  # <class '__main__.A'>
print(A) # <class '__main__.A'>

运行截图:

 4. 类装饰器(用的不多)

 func()

 以下完善写法:

代码如下:

class Test_Class:
    def __init__(self,func):
        print('这是初始化')
        self.func=func
    def __call__(self, *args, **kwargs):
        return self.func  # 返回值说明调用了fun函数
@Test_Class  # ====》调用Test_Class 函数并把fun函数传进去,然后通过参数func接受
def fun():
        print('这里是fun函数')
fun()()
# fun()

作业:测试type和isinstance两个函数,那个速度更加的快

 

与new方法、定制属性访问、描述符与装饰器知识点总结相似的内容:

new方法、定制属性访问、描述符与装饰器知识点总结

第一部分:__new__方法 思考: a. 我们创建实例是通过什么方法创建的呢? b. 类每次实例化的时候都会创建一个新的对象,如果要求类只能被实例化一次该怎么做呢? 通过单利模式实现 c.什么是单例模式(Singleton Pattern ) 1、确保一个类只有一个实例,而且自行实例化并向整个系统

Java JVM——10.对象实例化、内存布局与访问定位

对象实例化 对象创建方式 ★ new:最常见的方式、单例类中调用getInstance的静态类方法,XXXFactory的静态方法。 ★ Class的newInstance方法:在JDK9里面被标记为过时的方法,因为只能调用空参构造器。 ★ Constructor的newInstance(Xxx):

C#的重载决策

重载是许多编程语言支持的特性。所谓重载,就是指可以定义多个名称相同但参数(个数、类型和顺序)不同的方法(函数)。先来看一个例子: ```c# void Main() { char cvalue = 'a'; male m = new male(); m.write(cvalue); } class

设计模式之工厂模式

工厂模式是一种对象创建型模式,它提供了一种创建对象的最佳实践。在工厂模式中,我们在创建对象时不使用 new 关键字,而是通过调用工厂方法来创建对象。工厂方法是一种在子类中定义的方法,该方法负责实例化对象。工厂方法可以返回不同的对象类型,因此工厂模式可以创建一组相关或不相关的对象。这样就可以将对象的创

聊聊Spring的工厂方法与FactoryBean

概述 工厂方法是比较常见,常用的一种设计模式。FactoryBean是Spring提供的一种Bean注入IOC容器的方式。 工厂方法 在做日常开发时,一般都会避免直接new对象,而且将new的操作丢给IOC容器,但对于第三方系统的集成,我们不太好直接丢给IOC容器,此时可以通过工厂模式, 提供一个工

[转帖][译] BeyondProd:云原生安全的一种新方法(Google, 2019)

http://arthurchiao.art/blog/google-beyondprod-zh/ 译者序 本文翻译自 2019 年 Google 的一篇白皮书 BeyondProd: A new approach to cloud-native security, 介绍了其最新的云原生安全模型。

[转帖]PCIe Switch Adapter:不只是NVMe HBA?

https://new.qq.com/rain/a/20200906A02YFF00 前几天有朋友提到,某款标称5400RPM(每分钟转数)的HDD硬盘,实际上是7200 RPM。今天又看到国外网站上用声音(噪声)测试来判断的方法。 由于对硬盘的感情,我本来也想就此写点东西,并且我还想提出另外2种更

Java遍历Map集合的方法

Java中遍历Map集合的常用方式主要有以下几种: 1.使用keySet()方法遍历 遍历Map的key集合,然后通过key获取value。 Map map = new HashMap<>(); map.put("one", 1); map.put("two", 2

Python常见面试题007. 谈谈Python中__init__和__new__的区别

007. 谈谈Python中__init__和__new__的区别 python中关于dunder method双下方法,或magic method魔术方法的描述多在 https://docs.python.org/zh-cn/3.9/reference/datamodel.html#special

一文了解JVM(中)

HotSpot 虚拟机对象探秘 对象的创建 Header 解释 使用 new 关键字 调用了构造函数 使用 Class 的 newInstance 方法 调用了构造函数 使用 Constructor 类的newInstance 方法 调用了构造函数 使用 clone 方法 没有调用构造函数 使用反序