python中的特殊成员

54 阅读6分钟

python中的特殊成员

__new__()


class Foo(object):
    def __init__(self, name):
        self.name = name
obj = Foo("man!")

class Foo(object):
    def __init__(self, name):
        print("第二步:初始化对象,在空对象中创建数据")
        self.name = name

    def __new__(cls, *args, **kwargs):
        print("第一步:先创建空对象并返回")
        return object.__new__(cls)

obj = Foo("man!")

上面两段代码都可以正常执行,__new__ 是在Object类里自动实现的\

在第二段代码中,return object.__new__(cls) 返回给__init__

总的过程:
第一步先创建空对象并返回
第二步:初始化对象,在空对象中创建数据

call()

class Foo(object):
    def __call__(self, *args, **kwargs):
        print("执行call方法")


obj = Foo()
obj()

输出结果: 执行call方法

这个方法是python中是在对象后加括号,也可以理解为调用对象,最后是调用对象中call()

__str__

class Foo(object):

    def __str__(self):
        return "哈哈哈哈"

obj = Foo()
print(obj)

输出结果: 哈哈哈哈

一般我们直接打印对象会输出对象的地址,但是对象方法中使用了__str__,那么打印对象输出___str___方法的返回值

__dic__

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


obj = Foo("man",42)
print(obj.__dict__)

输出结果: {"name":"man","age":42}
调用___dic___函数,将当前对象属性以键值对形式输出

__getitem__、__setitem__、__delitem__

对象属性的操作与操作字典类似

class Foo(object):

    def __getitem__(self, item):
        print(item)

    def __setitem__(self, key, value):
        self.key = value

    def __delitem__(self, key):
        pass


obj = Foo("man", 42)

obj["x1"]
obj['x2'] = 123
del obj['x3']

输出结果: x1

添加了上面的几种方法,对象可以做类似字典的操作,方法内部实现什么可以自己写

__enter__、__exit__

上下文管理语法
1.with语法用于简化对象操作,自动执行enter和exit方法。
2.enter和exit方法用于上下文管理,确保对象操作前后正确关闭。
3.通过with语法可以简化代码,提高代码可读性和可维护性。

class Foo(object):

    def __enter__(self):
        print("进入了")
        return abc

    def __exit__(self, exc_type, exc_val, exc_tb):
        print("出去了")


obj = Foo()
# __enter__ return 返回的值给了data
with obj as data:
    print(123)
    print(data)

输出结果:

进入了
123
abc
出去了

上下文管理, 操作对象前后可以做一些操作\

比如操作数据库前, ___enter___函数来连接数据库, ___exit___函数来关闭数据库

# 伪代码
class SqlHelper(object):

    def __enter__(self):
        self.连接 = 连接数据库
        return 连接

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.连接.关闭

        
        
with SqlHelper() as 连接:
    连接.操作..
    
    
with SqlHelper() as 连接:
    连接.操作...

__add__ 等

允许对象间进行相加操作(为什么是__add__ 等,因为除了相加之外还有加减乘除等等的操作)

class Foo(object):
    def __init__(self, name):
        self.name = name

    def __add__(self, other):
        return "{}-{}".format(self.name, other.name)


v1 = Foo("man")
v2 = Foo("out")

# 对象+值,内部会去执行 对象.__add__方法,并将+后面的值当做参数传递过去。
v3 = v1 + v2
print(v3)

输出结果:mam - out

从上面的代码可以看出,当对象之间进行加法操作就会触发__add__方法

__iter__

迭代器

迭代器类型的定义:
1.当类中定义了 __iter__ 和 __next__ 两个方法。
2.__iter__ 方法需要返回对象本身,即:self
3. __next__ 方法,返回下一个数据,如果没有数据了,则需要抛出一个StopIteration的异常。
官方文档:docs.python.org/3/library/s…

# 创建 迭代器类型 :
	class IT(object):
        def __init__(self):
            self.counter = 0

        def __iter__(self):
            return self

        def __next__(self):
            self.counter += 1
            if self.counter == 3:
                raise StopIteration()
            return self.counter

# 根据类实例化创建一个迭代器对象:
    obj1 = IT()
    
    # v1 = obj1.__next__()
    # v2 = obj1.__next__()
    # v3 = obj1.__next__() # 抛出异常
    
    v1 = next(obj1) # obj1.__next__()
    print(v1)

    v2 = next(obj1)
    print(v2)

    v3 = next(obj1)
    print(v3)


    obj2 = IT()
    for item in obj2: 
     # 首先会执行迭代器对象的__iter__方法并获取返回值,一直去反复的执行 next(对象) 
        print(item)

for循环遍历一个迭代器对象时,会有三个步骤:

  1. for循环内部在循环时,先执行__iter__方法,获取一个迭代器对象,
  2. 迭代器对象支持通过next取值,如果取值结束则自动抛出StopIteration。
  3. 然后不断执行的next取值(有异常StopIteration则终止循环)。

生成器

创建生成器对象(内部是根据生成器类generator创建的对象),生成器类的内部也声明了:__iter__、__next__ 方法。 如果按照迭代器的定义来看,其实生成器类也是一种特殊的迭代器类(生成器也是一种特殊的迭代器)。

# 创建生成器函数
    def func():
        yield 1
        yield 2
    

    obj1 = func()
    
    v1 = next(obj1)
    print(v1)

    v2 = next(obj1)
    print(v2)
    # 到此抛出StopIteration
    v3 = next(obj1)
    print(v3)


    obj2 = func()
    for item in obj2:
        print(item)
        

可迭代对象

如果一个类中有__iter__方法且返回一个迭代器对象 ;则我们称以这个类创建的对象为可迭代对象。

class Foo(object):
    
    def __iter__(self):
        return 迭代器对象(生成器对象)
    
obj = Foo() # obj是 可迭代对象。

# 可迭代对象是可以使用for来进行循环,在循环的内部其实是先执行 __iter__ 方法,获取其迭代器对象,然后再在内部执行这个迭代器对象的next功能,逐步取值。
for item in obj:
    pass

给大家举一个例子

v1 = range(10)
# 发现v1的方法中只有__iter__,没有__next__,所以v1是可迭代对象
print("v1:", v1.__dir__())

# 可迭代对象通过__iter__()获得迭代器
v2 = v1.__iter__()逐步取值
# 迭代器执行__next__()
print(v2.__next__())
print(v2.__next__())
print(v2.__next__())
print(v2.__next__())

输出:

v1: ['__new__', '__repr__', '__hash__', '__getattribute__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__iter__', '__bool__', '__len__', '__getitem__', '__contains__', '__reversed__', '__reduce__', 'count', 'index', 'start', 'stop', 'step', '__doc__', '__str__', '__setattr__', '__delattr__', '__init__', '__reduce_ex__', '__subclasshook__', '__init_subclass__', '__format__', '__sizeof__', '__dir__', '__class__']
0
1
2
3

常见的数据结构:

l1 = list([1, 2, 3, 4, 5, 6])
print(dir(l1))

l2 = l1.__iter__()
print(l2.__next__())
print(l2.__next__())
print(l2.__next__())


输出:

['__add__', '__class__', '__class_getitem__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
1
2
3

l1是一个可迭代对象,因为在列表中声明了一个 __iter__ 方法并且返回一个迭代器对象。\

from collections.abc import Iterator, Iterable  # Iterator(迭代器), Iterable(迭代对象)

v1 = [11, 22, 33]
print( isinstance(v1, Iterator) )  # false,判断是否是迭代器;判断依据是__iter__ 和 __next__。
v2 = v1.__iter__()
print( isinstance(v2, Iterator) )  # True



v1 = [11, 22, 33]
print( isinstance(v1, Iterable) )  # True,判断依据是是否有 __iter__且返回迭代器对象。

v2 = v1.__iter__()
print( isinstance(v2, Iterable) )  # True,判断依据是是否有 __iter__且返回迭代器对象。

\






\