Python类的内置方法

目录

  • 1、new、init
  • 2、str、repr
  • 3、call
  • 4、del
  • 5、iter、next
  • 6、getitem、setitem、delitem
  • 7、getattr、setattr、delattr
  • 8、getatrribute
  • 9、enter、exit
  • 10、get、set、delete、描述符(研究中,待补充)

**(为了方便和美观,省略了各内置方法前后的__双下划线)**


1、new、init

__new__方法是真正的类构造方法,用于产生实例化对象(空属性)。重写__new__方法可以控制对象的产生过程。

__init__方法是初始化方法,负责对实例化对象进行属性值初始化,此方法必须返回None,__new__方法必须返回一个对象。重写__init__方法可以控制对象的初始化过程。

# 使用new来处理单例模式

class Student:
    __instance = None

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

    def sleep(self):
        print(‘sleeping...‘)

stu1 = Student()
stu2 = Student()

print(id(stu1), id(stu2))  # 两者输出相同
print(stu1 is stu2)  # True

个人感觉,__new__一般很少用于普通的业务场景,更多的用于元类之中,因为可以更底层的处理对象的产生过程。而__init__的使用场景更多。

2、str、repr

两者的目的都是为了显式的显示对象的一些必要信息,方便查看和调试。__str__print默认调用,__repr__被控制台输出时默认调用。即,使用__str__控制用户展示,使用__repr__控制调试展示。

# 默认所有类继承object类,object类应该有一个默认的str和repr方法,打印的是对象的来源以及对应的内存地址

class Student:
    def __init__(self, name, age):
        self.name = name
        self.age = age

stu = Student(‘zlw‘, 26)
print(stu)  # <__main__.Student object at 0x0000016ED4BABA90>
# 自定义str来控制print的显示内容,str函数必须return一个字符串对象
# 使用repr = str来偷懒控制台和print的显示一致

class Student:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __str__(self):
        return f‘{self.__class__}, {self.name}, {self.age}‘

    __repr__ = __str__

stu = Student(‘zlw‘, 26)
print(stu)  # <class ‘__main__.Student‘>, zlw, 26

3、call

__call__方法提供给对象可以被执行的能力,就像函数那样,而本质上,函数就是对象,函数就是一个拥有__call__方法的对象。拥有__call__方法的对象,使用callable可以得到True的结果,可以使用()执行,执行时,可以传入参数,也可以返回值。所以我们可以使用__call__方法来实现实例化对象作为装饰器:


# 检查一个函数的输入参数个数, 如果调用此函数时提供的参数个数不符合预定义,则无法调用。

# 单纯函数版本装饰器
def args_num_require(require_num):
    def outer(func):
        def inner(*args, **kw):
            if len(args) != require_num:
                print(‘函数参数个数不符合预定义,无法执行函数‘)
                return None

            return func(*args, **kw)
        return inner
    return outer

@args_num_require(2)
def show(*args):
    print(‘show函数成功执行!‘)

show(1)  # 函数参数个数不符合预定义,无法执行函数
show(1,2) # show函数成功执行!
show(1,2,3)  # 函数参数个数不符合预定义,无法执行函数

# 检查一个函数的输入参数个数,
# 如果调用此函数时提供的参数个数不符合预定义,则无法调用。

# 实例对象版本装饰器
class Checker:
    def __init__(self, require_num):
        self.require_num = require_num

    def __call__(self, func):
        self.func = func

        def inner(*args, **kw):
            if len(args) != self.require_num:
                print(‘函数参数个数不符合预定义,无法执行函数‘)
                return None

            return self.func(*args, **kw)
        return inner

@Checker(2)
def show(*args):
    print(‘show函数成功执行!‘)

show(1)  # 函数参数个数不符合预定义,无法执行函数
show(1,2) # show函数成功执行!
show(1,2,3)  # 函数参数个数不符合预定义,无法执行函数

4、del

__del__用于当对象的引用计数为0时自动调用。

__del__一般出现在两个地方:1、手工使用del减少对象引用计数至0,被垃圾回收处理时调用。2、程序结束时调用。

__del__一般用于需要声明在对象被删除前需要处理的资源回收操作

# 手工调用del 可以将对象引用计数减一,如果减到0,将会触发垃圾回收

class Student:

    def __del__(self):
        print(‘调用对象的del方法,此方法将会回收此对象内存地址‘)

stu = Student()  # 调用对象的__del__方法回收此对象内存地址

del stu

print(‘下面还有程序其他代码‘)
class Student:

    def __del__(self):
        print(‘调用对象的del方法,此方法将会回收此对象内存地址‘)

stu = Student()  # 程序直接结束,也会调用对象的__del__方法回收地址

5、iter、next

这2个方法用于将一个对象模拟成序列。内置类型如列表、元组都可以被迭代,文件对象也可以被迭代获取每一行内容。重写这两个方法就可以实现自定义的迭代对象。

# 定义一个指定范围的自然数类,并可以提供迭代

class Num:
    def __init__(self, max_num):
        self.max_num = max_num
        self.count = 0

    def __iter__(self):
        return self

    def __next__(self):
        if self.count < self.max_num:
            self.count += 1
            return self.count
        else:
            raise StopIteration(‘已经到达临界‘)

num = Num(10)
for i in num:
    print(i)  # 循环打印1---10

6、getitem、setitem、delitem

重写此系列方法可以模拟对象成列表或者是字典,即可以使用key-value的类型。

class StudentManager:
    li = []
    dic = {}

    def add(self, obj):
        self.li.append(obj)
        self.dic[obj.name] = obj

    def __getitem__(self, item):
        if isinstance(item, int):
            # 通过下标得到对象
            return self.li[item]
        elif isinstance(item, slice):
            # 通过切片得到一串对象
            start = item.start
            stop = item.stop
            return [student for student in self.li[start:stop]]
        elif isinstance(item, str):
            # 通过名字得到对象
            return self.dic.get(item, None)
        else:
            # 给定的key类型错误
            raise TypeError(‘你输入的key类型错误!‘)

class Student:
    manager = StudentManager()

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

        self.manager.add(self)

    def __str__(self):
        return f‘学生: {self.name}‘

    __repr__ = __str__

stu1 = Student(‘小明‘)
stu2 = Student(‘大白‘)
stu3 = Student(‘小红‘)
stu4 = Student(‘胖虎‘)

# 当做列表使用
print(Student.manager[0])  # 学生: 小明
print(Student.manager[-1])  # 学生: 胖虎
print(Student.manager[1:3])  # [学生: 大白, 学生: 小红]

# 当做字典使用
print(Student.manager[‘胖虎‘])  # 学生: 胖虎

7、getattr、setattr、delattr

当使用obj.x = y的时候触发对象的setattr方法,当del obj.x的时候触发对象的delattr方法。

当尝试访问对象的一个不存在的属性时 obj.noexist 会触发getattr方法,getattr方法是属性查找中优先级最低的。

可以重写这3个方法来控制对象属性的访问、设置和删除。

**特别注意:如果定义了getattr,而没有任何代码(即只有pass),则所有不存在的属性值都是None而不会报错,可以使用super().__getattr__()方法来处理**

class Student:
    def __getattr__(self, item):
        print(‘访问一个不存在的属性时候触发‘)
        return ‘不存在‘

    def __setattr__(self, key, value):
        print(‘设置一个属性值的时候触发‘)
        # self.key = value  # 这样会无限循环
        self.__dict__[key] = value

    def __delattr__(self, item):
        print(‘删除一个属性的时候触发‘)
        if self.__dict__.get(item, None):
            del self.__dict__[item]

stu = Student()
stu.name = ‘zlw‘  # 设置一个属性值的时候触发
print(stu.noexit)  # 访问一个不存在的属性时候触发 , 返回‘不存在‘
del stu.name  # 删除一个属性的时候触发

8、getatrribute

这是一个属性访问截断器,即,在你访问属性时,这个方法会把你的访问行为截断,并优先执行此方法中的代码,此方法应该是属性查找顺序中优先级最高的。

属性查找顺序:

实例的getattribute-->实例对象字典-->实例所在类字典-->实例所在类的父类(MRO顺序)字典-->实例所在类的getattr-->报错

class People:
    a = 200

class Student(People):
    a = 100

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

    def __getattr__(self, item):
        print(‘没有找到:‘, item)

    def __getattribute__(self, item):
        print(‘属性访问截断器‘)
        if item == ‘a‘:
            return 1
        return super().__getattribute__(item)

stu = Student(1)
print(stu.a)  # 1

9、enter、exit

这两个方法的重写可以让我们对一个对象使用with方法来处理工作前的准备,以及工作之后的清扫行为。


class MySQL:
    def connect(self):
        print(‘启动数据库连接,申请系统资源‘)

    def execute(self):
        print(‘执行sql命令,操作数据‘)

    def finish(self):
        print(‘数据库连接关闭,清理系统资源‘)

    def __enter__(self):  # with的时候触发,并赋给as变量
        self.connect()
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):  # 离开with语句块时触发
        self.finish()

with MySQL() as mysql:
    mysql.execute()

# 结果:
# 启动数据库连接,申请系统资源
# 执行sql命令,操作数据
# 数据库连接关闭,清理系统资源

10、get、set、delete、描述符(研究中,待补充)

原文地址:https://www.cnblogs.com/zzzlw/p/9286828.html

时间: 2024-09-29 09:10:44

Python类的内置方法的相关文章

python 类中内置方法的重写

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

python——类的内置方法

双下方法 __str__和__repr__ 改变对象的字符串显示__str__,__repr__ obj.__str__ str(obj)obj.__repr__ repr(obj) class Teacher: def __init__(self,name,salary): self.name = name self.salary = salary def __str__(self): return "Teacher's object :%s"%self.name def __rep

python类中内置方法之__call__

在python中自定义类时,如果该类实现了一个特殊方法__call__(),那么该类的实例则变成一个可调用的实例对象 如下 In [1]: class A():# 自定义一个A ...: def __call__(self,args): # 实现特殊方法__call__ ...: print(args) ...: In [2]: a = A() In [3]: a("__call__") __call__ a = A() # 对自定义的类A,实例化一个对象aa("__call

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

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

Python中类的内置方法与继承关系实例

1.类的内置方法 Python内部类:所谓内部类,就是在类的内部定义的类,主要目的是为了更好的抽象现实世界.例子:汽车是一个类,汽车的底盘轮胎也可以抽象为类,将其定义到汽车内中,而形成内部类,更好的描述汽车类,因为底盘轮胎是汽车的一部分. 内部类实例化方法: 方法1:直接使用外部类调用内部类方法2:先对外部类进行实例化,然后再实例化内部类 out_name = outclass_name() in_name = out_name.inclass_name() in_name.method() #

python常用数据类型内置方法介绍

熟练掌握python常用数据类型内置方法是每个初学者必须具备的内功. 一.整型 a = 100 a.xxx() class int(object): def bit_length(self): ##如果将某个整数用2进制表示,返回这个2进制所占bit位数. return 0 def conjugate(self, *args, **kwargs): ##共轭复数 @classmethod # known case def from_bytes(cls, bytes, byteorder, *ar

几个类的内置方法

# 类的内置方法 # 双下方法 # __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__(