python-面向对象类的内置方法

内置方法

__init__(self [, ...])

  • init对象实例化时被调用,该方法不能有返回值

__new__(cls [, ...])

  • 对象实例化时第一个被调用的方法
  • 默认里面的参数,会原封不动的传给init方法
  • 返回一个对象obj,通常返回class类对象,也可以返回其他类对象
# 当继承一个不可变类型时,又需要的时候使用
# 需求:输入字符串,输出的是大写的字符串
class CapStr(str):
    def __new__(cls,string):
        string = string.upper()
        return str.__new__(cls, string) # 调用父类new返回
a = CapStr("i love you")
print(a) # 输出 I LOVE YOU

__del__(self)

  • 当对象被删除时调用该方法(垃圾回收机制执行时,没有变量名指向这个数据值)
# __del__(self)

class C:
    def __init__(self):
        print("我是init,我被执行了")
    def __del__(self):
        print("我是del,我被执行了")
c1 = C() # 执行后,打印 我是init,我被执行了
c2 = c1 # 无打印
c3 = c2
del c3 # 无打印输出
del c2 # 无打印输出
del c1 # 执行后打印,我是del,我被执行了

__str__(self)**

  • 当对象被使用print()打印的时候调用
  • 当print()输出对象的时候,只要自己定义了__str__方法,那么就会打印从这个方法中return的数据
  • __str__方法需要返回一个字符串,当做这个对象的描述
class Cat:
    def __init__(self, new_name, new_age):
        self.name = new_name
        self.age = new_age  

    def __str__(self):
        """自定义 返回一个对象的描述信息"""
        # print(num)
        return "名字是:%s , 年龄是:%d" % (self.name, self.age)

c1 = Cat("Tom", 8)
print(c1) # 打印:名字是:Tom , 年龄是:8

__repr__(self)

  • 与__str__类似,当打印容器类型时不同
class A:
    def __init__(self, name):
        self.name = name

    def __str__(self):
        return "name:%s,----->from str" % self.name

    def __repr__(self):
        return "name:%s,----->from repr" % self.name

a1 = A("jack")
a2 = A("cindy")
print(a1)  # name:jack,----->from str
p = [a1, a2]

print(p)
# [name:jack,----->from repr, name:cindy,----->from repr]
# 当__repr__注释掉时,仅使用__str__时,打印的是地址
  • print单独一个对象,如print(a1)时,str和repr具有相同的功能,同时定义str和repr时,调用str
  • print对象的容器类型是,repr可以打印每个对象的字符串信息,str不行

属性访问:

__getattr__(self, name)

  • 当用户试图通过点调用一个不存在的属性时被触发

__getattribute__(self, name)

  • 当该类的属性被访问时调用,存在与否,均为被最先触发

__setattr__(self, name, value)

  • 当一个属性被设置时触发;如果该属性不存在就新增,类似于反射中的 setattr(obj, name, value)

__delattr__(self, name)

  • 当对象属性被删除时触发

demo:

class C:

    def __getattribute__(self, name):
        print("getattribute")
        super().__getattribute__(name) # 调用基类的该方法
        # return self.name 会无限循环
    def __getattr__(self, name):
        print("getattr")
    def __setattr__(self, name, value):
        print("setattr")
        super().__setattr__(name, value)
        # self.name = value 会无限循环
    def __delattr__(self, name):
        print("delattr")
        super().__delattr__(name)
        # del self.name 会无限循环
c = C()
print(c.x) # 打印 getattributr/getattr
c.x = 10 # 打印 setattr
print(c.x) # 打印 getattribute
del c.x # 打印 delattr

注意:所有的属性方法,注意无限循环

  • 可以使用调用基类的相应方法
  • 也可以直接操作属性字典,如self.__dict__[key] = value
  • 当__getattribute__与__getattr__同时存在时,只会执行__getattribute__,除非__getattribute__在执行过程中抛出异常AttributeError

__getitem__

__setitem__

__delitem__

item 系列以字典的形式访问属性时被调用

以字典key的方式访问是否存在的属性时,都会触发__getitem__,这一点有别于__getattr__

class Foo:
    def __init__(self, a):
        self.a = a

    def __getitem__(self, item):
        print("__getitem__被触发了")

    def __getattr__(self, item):
        print("__getattr__被触发了")

f = Foo("word")
f["a"]
f["b"]

#output:
__getitem__被触发了
__getitem__被触发了

使用[]设置实例属性时 ,触发__setitem__

class Foo:
    def __setitem__(self, key, value):
        print("__setitem__被触发了")

    def __setattr__(self, key, value):
        print("__setattr__被触发了")

f = Foo()
f.x = 10
f["y"] = 10

#output:
__setattr__被触发了
__setitem__被触发了

使用[]删除实例属性时 ,触发__delitem__

class Foo:
    def __init__(self, a, b):
        self.a = a
        self.b = b

    def __delitem__(self, key):
        print("__delitem__被触发了")

    def __delattr__(self, key):
        print("__delattr__被触发了")

f = Foo("one", "two")
del f.a
del f["b"]

#output:
__delattr__被触发了
__delitem__被触发了

描述符:

描述符是什么

  • 描述符本质是一个新式类,**在这个新式类中,至少实现了__get__()、__set__()、 __delete__()**中的一个或多个,这个也被成为描述符协议。

描述符干什么

  • 描述符的作用是用来代理另一个类的属性(必须把描述符的对象定义成这个类的类属性,不能定义到构造函数中)。

调用属性时,触发__get__()

**为属性赋值时,触发、__set__()**

采用del删除属性时,触发 __delete__()

__get__

__set__

__delete__

定义一个描述符:下面这个新式类就是描述符

class Foo:
    def __get__(self, instance, owner):
        print("我是get...")
    def __set__(self,instance, value):
        print("我是set...")
    def __delete__(self, instance):
        print("我是delete...")

描述符类实例化的对象,进行属性操作并不会触发这三个方法的执行

描述符分两种:

  • 数据描述符,至少含有__get__和 __set__ 的
  • 非数据描述符,没有实现 __set__的

描述符严格遵循优先级,优先级由高到低分别是:

  • 类属性
  • 数据描述符
  • 实例属性
  • 非数据属性
  • 找不到的属性触发__getattr__()

原文地址:https://www.cnblogs.com/liuxu2019/p/12115951.html

时间: 2024-10-09 10:02:05

python-面向对象类的内置方法的相关文章

Python进阶-----类的内置方法__getattribute__

__getattribute__ 方法功能: 1 调用属性会触发该功能,属性存在则会返回相应的值:2 如果属性不存在则会抛出异常AttributeError,所以可以自定义异常信息3 存在__getattr__,若有异常出现则会传递给__getattr__用来接收,执行操作 class Foo: def __init__(self,x): self.x=x def __getattr__(self, item): print('执行的是我') # return self.__dict__[ite

类的属性、类的方法、类的内置方法

类的属性 变量在类中称为类的属性,函数在类中称为类的方法,类的属性分为以下几种: (1) 公有属性:在类中和类外都能调用的属性,定义的时候与变量的定义一致,如 color = 'yellow'(2) 私有属性:不能在类外及被类以外的函数调用,定义的时候以双下划线开头,如__color = 'yellow' (3) 内置属性: 由系统在定义类的时候默认添加的,定义的时候以前后双下划线构成,如 dict #!/usr/bin/env python class People(object): colo

铁乐学python_day24_面向对象进阶1_内置方法

题外话1: 学习方法[wwwh] what where why how 是什么,用在哪里,为什么,怎么用 学习到一个新知识点的时候,多问问上面的四个问题,并了解和实践透彻. 什么是反射? 先不说枯燥的概念,你可以自己总结出来,对于python中的反射,什么时候会用到? 需要使用字符串数据类型的变量名来使用变量的时候用到反射. (通过字符串的形式操作对象相关的属性和方法.) 关键词:字符串 使用到字符串的场景多在: 1)文件中存储的是字符串, 2)网络上能传递的也最接近字符串, 3)用户输入的(用

几个类的内置方法

# 类的内置方法 # 双下方法 # __str__ # 当类中定义了__str__方法后,print(这个类对象时),会调用__str__. 或者格式化%s输出对象时,都会触发__str__ # __repr__ # 当类中定义了__repr__方法后,print(repr(a)),就会调用a对象中的__repr__()方法.格式化输出用%r时同样会调用__repr__ # 同样对象中如果没有定义__repr__方法,那么就会调用父类中的__repr__ # __repr__是__str__的备

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

''' 类的内置方法(魔方方法): 凡是在类内部定义的,__开头__结尾的方法,都是类的内置方法,也称为魔法方法 类的内置方法,会在某种条件满足下自动触发. __new__:在__init__触发前,自动触发.调用该类时,内部会通过__new__来产生一个新的对象. __init_:在调用类时自动触发.通过__new__产生的对象自动调用__init__. ''' class Demo(object): def __new__(cls, *args, **kwargs): print('from

Python之面向对象:类的内置方法

1.def __add__(self,other): c1+c2 两个实例的加法操作就是执行__add__()方法 2.__str__(self): print一个实例的时候,执行的是__str__()这个内置方法 eg: class Vector(object): def __init__(self,a,b): self.a = a self.b = b def __str__(self): return 'Vector(%d,%d)'%(self.a,self.b) def __add__(

python全栈开发【第十七篇】面向对象反射和内置方法

一.静态方法(staticmethod)和类方法(classmethod) 类方法:有个默认参数cls,并且可以直接用类名去调用,可以与类属性交互(也就是可以使用类属性) 静态方法:让类里的方法直接被类调用,就像正常调用函数一样 类方法和静态方法的相同点:都可以直接被类调用,不需要实例化 类方法和静态方法的不同点: 类方法必须有一个cls参数表示这个类,可以使用类属性 静态方法不需要参数 绑定方法:分为普通方法和类方法 普通方法:默认有一个self对象传进来,并且只能被对象调用-------绑定

Python之路(第二十六篇) 面向对象进阶:内置方法

一.__getattribute__ object.__getattribute__(self, name) 无条件被调用,通过实例访问属性.如果class中定义了__getattr__(),则__getattr__()不会被调用(除非显示调用或引发AttributeError异常) class Foo: ? def __init__(self,x): self.x = x ? def __getattr__(self, item): print("执行__getattr__") ?

面向对象:类的内置方法

__str__和__repr__:实例化一个对象,该对象的返回值是一个指向这个类的内存地址 class A: pass a = A() print(a) #打印: <__main__.A object at 0x000001FA526DA108> 自定义__str__和__repr__方法: class Func: pass def __str__(self): return '我是自定义的str' def __repr__(self): return '我是自定义的repr' a = Fun

python 类中内置方法的重写

为达成目的,经常会在类中将一些内置方法进行重写,最常见的例如__setattr__,下面就通过内置属性,来查看重写会带来什么变化 先定义一个测试用的类,代码如下 class base: def __init__(self): pass inspect.getmembers(base): # 查看内置属性 打印结果如下 ('__class__', <class 'type'>) ('__delattr__', <slot wrapper '__delattr__' of 'object'