python中魔法函数用法总结

1、__init__

        魔法函数__init__是Python中的一个特殊方法,用于初始化对象的属性。当创建一个新的对象时,__init__方法会自动调用。

__init__方法的定义格式如下:

def __init__(self, 参数1, 参数2, ...):
    # 初始化代码

        __init__方法的第一个参数通常是self,表示要初始化的对象本身。接下来的参数是用于初始化对象属性的值。

下面是__init__方法的一些常见用法:

1.1 初始化对象的属性

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

        在这个例子中,__init__方法接受两个参数name和age,并将它们分别赋值给对象的name和age属性。

1.2 执行其他初始化操作

        __init__方法不仅可以用于初始化对象的属性,还可以执行其他需要在对象创建时进行的初始化操作。例如,可以在__init__方法中打开文件、建立数据库连接等。

def __init__(self):
    self.file = open('data.txt', 'r')
    self.db = connect('localhost', 'user', 'password', 'database')

        在这个例子中,__init__方法在对象创建时打开了一个文件和建立了一个数据库连接。

1.3 继承父类的__init__方法

        如果一个类继承了其他类,它的__init__方法可以调用父类的__init__方法,以初始化父类的属性。

class Child(Parent):
    def __init__(self, name, age, school):
        super().__init__(name, age)
        self.school = school

        在这个例子中,Child类继承了Parent类,并在自己的__init__方法中调用了父类的__init__方法,以初始化父类的属性。然后,它还额外定义了一个school属性。

示例代码:

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

    def user_info(self):
        print("name:", self.name, ", age:", self.age)


class Child(Parent):
    def __init__(self, school):
        self.school = school

    def student_info(self):
        print("school:", self.school)


class Child2(Parent):
    def __init__(self, name, age, school):
        super().__init__(name, age)
        self.school = school

    def student_info(self):
        print("school:", self.school)


if __name__ == '__main__':
    parent = Parent("dgw", 26)
    parent.user_info()

    child = Child("清华大学")
    child.student_info()
    # child.user_info()  这行直接使用报错,AttributeError: 'Child' object has no attribute 'name'

    child2 = Child2("dgw", 26, "清华大学")
    child2.student_info()
    child2.user_info()

运行结果:

python中魔法函数用法总结_第1张图片

        总之,__init__方法是Python中的一个特殊方法,用于初始化对象的属性和执行其他初始化操作。通过定义__init__方法,可以在创建对象时进行必要的初始化工作。

2、__str__

        魔法函数__str__是Python中的一个特殊方法,用于返回对象的字符串表示形式。当使用内置函数str()或print()打印一个对象时,会自动调用对象的__str__方法。

__str__方法的定义格式如下:

def __str__(self):
    # 返回对象的字符串表示形式

__str__方法应返回一个字符串,表示对象的可读性良好的字符串表示形式。

下面是__str__方法的一些常见用法:

2.1 返回对象的属性值

def __str__(self):
    return f"Name: {self.name}, Age: {self.age}"

在这个例子中,__str__方法返回一个包含对象的name和age属性值的字符串。

示例代码1:

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

    def user_info(self):
        print("name:", self.name, ", age:", self.age)

    def __str__(self):
        return f"Name: {self.name}, Age: {self.age}"


if __name__ == '__main__':
    parent = Parent("dgw", 26)
    parent.user_info()
    print(parent)
    print(parent.__str__)
    print(parent.__str__())

运行结果:

python中魔法函数用法总结_第2张图片

示例代码2:

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

    def __str__(self):
        return f"Name: {self.name}, Age: {self.age}"


class Parent2(object):
    """未使用__str__方法"""
    def __init__(self, name, age):
        self.name = name
        self.age = age


if __name__ == '__main__':
    parent = Parent("dgw", 26)
    print(parent)
    print(parent.__str__)
    print(parent.__str__())
    parent2 = Parent2("dgw", 26)
    print(parent2)
    print(parent2.__str__)
    print(parent2.__str__())

运行结果:

python中魔法函数用法总结_第3张图片

2.2 返回对象的描述信息

__str__方法可以返回对象的描述信息,如对象的类型、地址等。

def __str__(self):
    return f"Object of {type(self).__name__} at {hex(id(self))}"

在这个例子中,__str__方法返回一个描述对象类型和地址的字符串。

示例代码:

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

    def user_info(self):
        print("name:", self.name, ", age:", self.age)

    def __str__(self):
        return f"Object of {type(self).__name__} at {hex(id(self))}"


if __name__ == '__main__':
    parent = Parent("dgw", 26)
    parent.user_info()
    print(parent)
    print(parent.__str__)
    print(parent.__str__())

运行结果:

python中魔法函数用法总结_第4张图片

2.3 自定义对象的字符串表示形式

__str__方法可以根据需要自定义对象的字符串表示形式。

def __str__(self):
    if self.gender == 'M':
        return f"Mr. {self.name}"
    elif self.gender == 'F':
        return f"Ms. {self.name}"
    else:
        return f"{self.name}"

在这个例子中,__str__方法根据对象的gender属性返回不同的字符串表示形式。

总之,__str__方法是Python中的一个特殊方法,用于返回对象的字符串表示形式。通过定义__str__方法,可以自定义对象的字符串表示,使其更具可读性和表达力。

3、__repr__

        魔法函数__repr__是Python中的一个特殊方法,用于返回对象的“官方”字符串表示形式。当使用内置函数repr()或交互式解释器打印一个对象时,会自动调用对象的__repr__方法。

__repr__方法的定义格式如下:

def __repr__(self):
    # 返回对象的官方字符串表示形式

        __repr__方法应返回一个字符串,表示对象的官方字符串表示形式。它通常应该是一个可以通过eval()函数重新创建对象的字符串。

下面是__repr__方法的一些常见用法:

3.1 返回对象的属性值

def __repr__(self):
    return f"Person(name='{self.name}', age={self.age})"

        在这个例子中,__repr__方法返回一个包含对象的name和age属性值的字符串,可以通过eval()函数重新创建对象。

3.2 返回对象的描述信息

__repr__方法可以返回对象的描述信息,如对象的类型、地址等。

def __repr__(self):
    return f"<{type(self).__name__} at {hex(id(self))}>"

在这个例子中,__repr__方法返回一个描述对象类型和地址的字符串。

3.3 自定义对象的字符串表示形式

__repr__方法可以根据需要自定义对象的字符串表示形式。

def __repr__(self):
    return f"Point({self.x}, {self.y})"

在这个例子中,__repr__方法返回一个自定义的字符串表示形式,表示一个点对象的坐标。

总之,__repr__方法是Python中的一个特殊方法,用于返回对象的“官方”字符串表示形式。通过定义__repr__方法,可以自定义对象的官方字符串表示,使其更具可读性和表达力。这种字符串表示形式通常应该是一个可以通过eval()函数重新创建对象的字符串。

详见博文:python中repr()函数用法详解_python repr_IT之一小佬的博客-CSDN博客

4、__len__

        魔法函数__len__是Python中的一个特殊方法,用于返回对象的长度。当使用内置函数len()对一个对象进行操作时,会自动调用对象的__len__方法。

__len__方法的定义格式如下:

def __len__(self):
    # 返回对象的长度

__len__方法应返回一个整数,表示对象的长度。

__len__方法通常用于自定义容器类,如列表、字符串、字典等。下面是__len__方法的一些常见用法:

4.1 返回列表或字符串的长度

def __len__(self):
    return len(self.data)

在这个例子中,__len__方法返回对象的data属性的长度,即返回列表或字符串的长度。

示例代码:

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

    def __len__(self):
        return len(self.name)


if __name__ == '__main__':
    parent = Parent("dgw", 26)
    print(len(parent))

运行结果:

4.2 返回字典的键的数量

def __len__(self):
    return len(self.keys())

在这个例子中,__len__方法返回字典的键的数量,即返回字典中元素的数量。

4.3 返回自定义容器的元素数量

def __len__(self):
    count = 0
    for item in self:
        count += 1
    return count

在这个例子中,__len__方法遍历自定义容器对象并计数元素的数量,然后返回数量。

总之,__len__方法是Python中的一个特殊方法,用于返回对象的长度。通过定义__len__方法,可以自定义容器类的长度计算方式。这样,在使用内置函数len()对自定义容器进行操作时,会自动调用__len__方法来获取容器的长度。

5、__getitem__

        魔法函数__getitem__是Python中的一个特殊方法,用于实现对象的索引访问。当使用索引操作符[]对一个对象进行操作时,会自动调用对象的__getitem__方法。

__getitem__方法的定义格式如下:

def __getitem__(self, index):
    # 返回指定索引的元素

__getitem__方法应接受一个参数index,表示要获取的元素的索引,并返回对应的元素。

__getitem__方法通常用于自定义容器类,如列表、字符串、字典等。下面是__getitem__方法的一些常见用法:

5.1 获取列表或字符串中的元素

def __getitem__(self, index):
    return self.data[index]

在这个例子中,__getitem__方法返回对象的data属性中指定索引的元素,即返回列表或字符串中对应索引的元素。

示例代码:

class Test(object):
    def __init__(self, data):
        self.data = data

    def __getitem__(self, item):
        try:
            return self.data[item]
        except IndexError as e:
            print(e)


class Test2(object):
    def __init__(self, data):
        self.data = data

    def getitem(self, item):
        try:
            return self.data[item]
        except IndexError as e:
            print(e)


if __name__ == '__main__':
    test = Test([1, 2, 3, 4, 5, 6])
    ret = test[3]
    print(ret)
    ret = test[7]
    print(ret)
    print("*" * 100)
    test2 = Test2([1, 2, 3, 4, 5, 6])
    # ret2 = test2[3]  # 报错:TypeError: 'Test2' object is not subscriptable
    # print(ret2)

运行结果:

python中魔法函数用法总结_第5张图片

5.2 获取字典中的值

def __getitem__(self, key):
    return self.data[key]

在这个例子中,__getitem__方法返回字典中指定键的值,即返回字典中对应键的值。

5.3 获取自定义容器中的元素

def __getitem__(self, index):
    for i, item in enumerate(self):
        if i == index:
            return item
    raise IndexError("Index out of range")

        在这个例子中,__getitem__方法遍历自定义容器对象,根据索引值找到对应的元素并返回。如果索引超出范围,则抛出IndexError异常。

        总之,__getitem__方法是Python中的一个特殊方法,用于实现对象的索引访问。通过定义__getitem__方法,可以自定义容器类的索引访问方式。这样,在使用索引操作符[]对自定义容器进行操作时,会自动调用__getitem__方法来获取指定索引的元素。

6、__setitem__

        魔法函数__setitem__是Python中的一个特殊方法,用于实现对象的索引赋值。当使用索引操作符[]对一个对象进行赋值操作时,会自动调用对象的__setitem__方法。

__setitem__方法的定义格式如下:

def __setitem__(self, index, value):
    # 对指定索引进行赋值操作

__setitem__方法应接受两个参数,index表示要赋值的元素的索引,value表示要赋给该索引的值。

__setitem__方法通常用于自定义容器类,如列表、字符串、字典等。下面是__setitem__方法的一些常见用法:

6.1 修改列表或字符串中的元素

def __setitem__(self, index, value):
    self.data[index] = value

在这个例子中,__setitem__方法将对象的data属性中指定索引的元素修改为指定的值。

6.2 修改字典中的值

def __setitem__(self, key, value):
    self.data[key] = value

在这个例子中,__setitem__方法将字典中指定键的值修改为指定的值。

示例代码:

class Test(object):
    def __init__(self):
        self.dic = {
            "name": "张三",
            "age": 26
        }

    def __getitem__(self, item):
        return self.dic[item]

    def __setitem__(self, key, value):
        self.dic[key] = value


if __name__ == '__main__':
    test = Test()
    ret = test['name']
    print(ret)
    test['name'] = '李四'
    print(test['name'])
    test['sex'] = '男'
    print(test['sex'])

运行结果:

python中魔法函数用法总结_第6张图片

6.3 修改自定义容器中的元素

def __setitem__(self, index, value):
    for i, item in enumerate(self):
        if i == index:
            self[i] = value
            return
    raise IndexError("Index out of range")

        在这个例子中,__setitem__方法遍历自定义容器对象,根据索引值找到对应的元素并修改为指定的值。如果索引超出范围,则抛出IndexError异常。

        总之,__setitem__方法是Python中的一个特殊方法,用于实现对象的索引赋值。通过定义__setitem__方法,可以自定义容器类的索引赋值方式。这样,在使用索引操作符[]对自定义容器进行赋值操作时,会自动调用__setitem__方法来修改指定索引的元素。

7、__delitem__

        魔法函数__delitem__是Python中的一个特殊方法,用于实现对象的索引删除操作。当使用del关键字删除一个对象的索引时,会自动调用对象的__delitem__方法。

__delitem__方法的定义格式如下:

def __delitem__(self, index):
    # 删除指定索引的元素

__delitem__方法应接受一个参数index,表示要删除的元素的索引。

__delitem__方法通常用于自定义容器类,如列表、字符串、字典等。下面是__delitem__方法的一些常见用法:

7.1 删除列表或字符串中的元素

def __delitem__(self, index):
    del self.data[index]

在这个例子中,__delitem__方法将对象的data属性中指定索引的元素删除。

7.2 删除字典中的键值对

def __delitem__(self, key):
    del self.data[key]

在这个例子中,__delitem__方法将字典中指定键的键值对删除。

示例代码:

class Test(object):
    def __init__(self):
        self.dic = {
            "name": "张三",
            "age": 26
        }

    def __delitem__(self, key):
        del self.dic[key]

    def __str__(self):
        return f"dic: {self.dic}"


if __name__ == '__main__':
    test = Test()
    print(test)
    del test['age']
    print(test)

运行结果:

python中魔法函数用法总结_第7张图片

7.3 删除自定义容器中的元素

def __delitem__(self, index):
    del self[index]

在这个例子中,__delitem__方法递归调用自定义容器对象的__delitem__方法,删除指定索引的元素。

总之,__delitem__方法是Python中的一个特殊方法,用于实现对象的索引删除操作。通过定义__delitem__方法,可以自定义容器类的索引删除方式。这样,使用del关键字删除对象的索引时,会自动调用__delitem__方法来删除指定索引的元素。

8、__getattr__

        魔法函数__getattr__是Python中的一个特殊方法,用于在访问对象的不存在的属性时自动调用。当访问一个对象的属性时,如果该属性不存在,Python会自动调用对象的__getattr__方法。

__getattr__方法的定义格式如下:

def __getattr__(self, name):
    # 处理不存在的属性

__getattr__方法应接受一个参数name,表示访问的属性名。

__getattr__方法常用于在对象的属性不存在时进行动态处理,一些常见的用法有:

8.1 提供默认值

def __getattr__(self, name):
    return "default value"

在这个例子中,如果访问的属性不存在,__getattr__方法会返回一个默认值。

示例代码:

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

    def __getattr__(self, item):
        return f"{item} is not exist!"


if __name__ == '__main__':
    test = Test('dgw')
    print(test.name)
    print(test.age)

运行结果:

python中魔法函数用法总结_第8张图片

8.2 动态计算属性

def __getattr__(self, name):
    if name == "attribute":
        return 10
    else:
        raise AttributeError(f"'{self.__class__.__name__}' object has no attribute '{name}'")

        在这个例子中,根据属性名动态计算属性的值。如果访问的属性名是attribute,__getattr__方法返回值为10;否则,抛出AttributeError异常。

8.3 访问不存在的属性时触发其他操作

def __getattr__(self, name):
    print(f"Accessing non-existent attribute: {name}")
    return None

在这个例子中,__getattr__方法在访问不存在的属性时会打印一条消息,并返回None。

总之,__getattr__方法是Python中的一个特殊方法,用于在访问对象的不存在的属性时自动调用。通过定义__getattr__方法,可以自定义对象在访问不存在的属性时的行为。

9、__setattr__

        魔法函数__setattr__是Python中用于处理对象属性设置的特殊方法。当给一个对象的属性赋值时,Python会自动调用对象的__setattr__方法。

__setattr__方法的定义格式如下:

def __setattr__(self, name, value):
    # 处理属性设置

__setattr__方法接收三个参数,self表示对象本身,name表示要设置的属性名,value表示要设置的属性值。

__setattr__方法的用法详解如下:

9.1 防止属性被修改

def __setattr__(self, name, value):
    if name == "attribute":
        raise AttributeError("Cannot modify attribute")
    else:
        self.__dict__[name] = value

        在这个例子中,如果要设置的属性名是attribute,__setattr__方法会抛出AttributeError异常,阻止属性的修改。否则,会将属性值存储在对象的__dict__属性中。

示例代码:

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

    def __getattr__(self, item):
        return f"{item} is not exist!"

    def __setattr__(self, key, value):
        self.__dict__[key] = value


if __name__ == '__main__':
    test = Test('dgw')
    print(test.name)
    print(test.age)
    test.age = 26
    print(test.age)

运行结果:

python中魔法函数用法总结_第9张图片

9.2 拦截属性设置操作

def __setattr__(self, name, value):
    print(f"Setting attribute: {name} = {value}")
    self.__dict__[name] = value

        在这个例子中,__setattr__方法在设置属性时会打印一条消息,并将属性值存储在对象的__dict__属性中。这可以用于拦截属性的设置操作,并进行相应的处理。

9.3 避免无限递归

def __setattr__(self, name, value):
    if name == "attribute":
        self.attribute = value
    else:
        self.__dict__[name] = value

        在这个例子中,如果要设置的属性名是attribute,__setattr__方法会将值直接赋给self.attribute,而不会调用__setattr__方法,避免了无限递归的问题。

示例代码:

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

    def __setattr__(self, key, value):
        self.__dict__[key] = value


if __name__ == '__main__':
    test = Test('dgw')
    print(test.name)
    if not getattr(test, 'age', None):
        test.age = 26
        setattr(test, 'sex', '男')
    print(test.age)
    print(test.sex)

运行结果:

python中魔法函数用法总结_第10张图片

        总结来说,__setattr__方法是Python中的一个特殊方法,用于在给对象的属性赋值时自动调用。通过定义__setattr__方法,可以自定义对象在属性设置时的行为。可以用于防止属性被修改、拦截属性设置操作或避免无限递归。这使得对象的属性设置行为更加灵活和控制。

10、__call__

        魔法函数__call__是Python中用于使对象可调用的特殊方法。当一个对象被调用时,Python会自动调用该对象的__call__方法。

__call__方法的定义格式如下:

def __call__(self, *args, **kwargs):
    # 处理调用操作

__call__方法接收的参数包括self表示对象本身,*args表示任意数量的位置参数,**kwargs表示任意数量的关键字参数。

__call__方法的用法详解如下:

10.1 将对象作为函数调用

class MyClass:
    def __call__(self, *args, **kwargs):
        print("Calling MyClass")

obj = MyClass()
obj()

在这个例子中,MyClass类定义了__call__方法,当obj对象被调用时,__call__方法会被自动调用,输出"Calling MyClass"。

示例代码:

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

    def __call__(self, *args, **kwargs):
        print(f"name: {self.name}")


if __name__ == '__main__':
    test = Test('dgw')
    print(test.name)
    test()

运行结果:

python中魔法函数用法总结_第11张图片

10.2 实现函数式编程风格

class Adder:
    def __init__(self, num):
        self.num = num

    def __call__(self, x):
        return self.num + x

add_5 = Adder(5)
result = add_5(10)
print(result)  # 输出 15

        在这个例子中,Adder类定义了__call__方法,使得对象可以像函数一样被调用。add_5对象被调用时,会将传入的参数与self.num相加并返回结果。

10.3 实现装饰器

class Decorator:
    def __init__(self, func):
        self.func = func

    def __call__(self, *args, **kwargs):
        print("Before calling function")
        result = self.func(*args, **kwargs)
        print("After calling function")
        return result

@Decorator
def my_function():
    print("Inside my_function")

my_function()

        在这个例子中,Decorator类定义了__call__方法,使得对象可以像装饰器一样被调用。my_function函数被调用时,会先执行Decorator对象的__call__方法进行装饰操作,然后再执行原函数。

示例代码:

class Decorator(object):
    def __init__(self, func):
        self.func = func

    def __call__(self, *args, **kwargs):
        print("Before calling function")
        result = self.func(*args, **kwargs)
        print("After calling function")
        return result


@Decorator
def my_func(x, y):
    return x + y


if __name__ == '__main__':
    ret = my_func(5, 6)
    print(ret)

运行结果:

python中魔法函数用法总结_第12张图片

        总结来说,__call__方法是Python中的一个特殊方法,用于使对象可调用。通过定义__call__方法,可以让对象像函数一样被调用,实现函数式编程风格或实现装饰器等功能。这使得对象的调用行为更加灵活和自定义。

详见博文:python中的__call__用法详解_python def __call___IT之一小佬的博客-CSDN博客

11、__next__

        魔法函数__next__()是迭代器协议中的一个特殊方法,用于定义一个可迭代对象的迭代行为。当使用内置函数next()来迭代一个可迭代对象时,实际上是调用了该对象的__next__()方法。下面是__next__()方法的使用详解。

class MyIterator:
    def __init__(self, data):
        self.data = data
        self.index = 0

    def __iter__(self):
        return self

    def __next__(self):
        if self.index >= len(self.data):
            raise StopIteration
        value = self.data[self.index]
        self.index += 1
        return value

# 创建一个可迭代对象
my_iter = MyIterator([1, 2, 3, 4, 5])

# 使用迭代器进行迭代
for num in my_iter:
    print(num)

运行结果:

python中魔法函数用法总结_第13张图片

        在上述示例中,我们定义了一个名为MyIterator的迭代器类,它包含了__init__()构造方法、__iter__()方法和__next__()方法。__init__()方法用于初始化迭代器对象的数据和索引。__iter__()方法返回迭代器对象本身,因为迭代器对象也是可迭代的。__next__()方法定义了迭代器对象的迭代逻辑,每次迭代时会返回一个值,并更新索引。当索引超出范围时,抛出StopIteration异常来标识迭代结束。

        在实际使用中,我们可以使用next()函数来手动调用迭代器的__next__()方法来获取下一个值,或者使用for循环来自动迭代可迭代对象。在for循环中,每次迭代都会自动调用迭代器的__next__()方法,并将返回的值赋给循环变量。

12、__iter__

        魔法函数__iter__()是迭代器协议中的一个特殊方法,用于定义一个可迭代对象的迭代行为。当一个对象被用于for循环或者使用内置函数iter()进行迭代时,实际上是调用了该对象的__iter__()方法。下面是__iter__()方法的使用详解。

class MyIterable:
    def __init__(self, data):
        self.data = data

    def __iter__(self):
        return MyIterator(self.data)

class MyIterator:
    def __init__(self, data):
        self.data = data
        self.index = 0

    def __iter__(self):
        return self

    def __next__(self):
        if self.index >= len(self.data):
            raise StopIteration
        value = self.data[self.index]
        self.index += 1
        return value

# 创建一个可迭代对象
my_iterable = MyIterable([1, 2, 3, 4, 5])

# 使用迭代器进行迭代
for num in my_iterable:
    print(num)

运行结果:

python中魔法函数用法总结_第14张图片

        在上述示例中,我们定义了一个名为MyIterable的可迭代对象类和一个名为MyIterator的迭代器类。MyIterable类中定义了__iter__()方法,该方法返回一个迭代器对象。在MyIterable类的构造方法中,我们将迭代器对象的数据作为参数传入,并保存在实例变量data中。

        MyIterator类中也定义了__iter__()方法,该方法返回迭代器对象本身,因为迭代器对象也是可迭代的。__next__()方法与前面示例中的一样,定义了迭代器对象的迭代逻辑。

        在实际使用中,我们可以使用for循环来自动迭代可迭代对象。在for循环中,首先会调用可迭代对象的__iter__()方法来获取一个迭代器对象,然后每次迭代都会自动调用迭代器对象的__next__()方法,并将返回的值赋给循环变量。

        需要注意的是,可迭代对象和迭代器对象可以是同一个类的实例,也可以是不同的类的实例。但是,可迭代对象必须实现__iter__()方法来返回一个迭代器对象,而迭代器对象必须实现__iter__()方法和__next__()方法。

13、__name__

        魔法函数__name__是一个特殊的属性,用于获取一个对象的名称。在Python中,__name__属性可以用于获取函数、类、模块等对象的名称。下面是__name__属性的使用详解。

13.1 获取函数的名称:

def my_function():
    pass

print(my_function.__name__)
# 输出:"my_function"

在上述示例中,my_function.__name__返回函数my_function的名称。

示例代码:

def my_function():
    return 666


if __name__ == '__main__':
    test = my_function
    print(test.__name__)  # 输出:my_function
    test = my_function()
    # print(test.__name__)  # 抛出异常:AttributeError: 'int' object has no attribute '__name__'. Did you mean: '__ne__'?

运行结果:

python中魔法函数用法总结_第15张图片

13.2 获取类的名称:

class MyClass:
    pass

print(MyClass.__name__)
# 输出:"MyClass"

在上述示例中,MyClass.__name__返回类MyClass的名称。

示例代码:

class MyClass(object):
    def func(self):
        print("__name__ is {}".format(self.__class__.__name__))


if __name__ == '__main__':
    test = MyClass
    print(test.__name__)  # 输出:MyClass
    test = MyClass()
    test.func()  # 输出: __name__ is MyClass
    print(test.__name__)  # 抛出异常:AttributeError: 'MyClass' object has no attribute '__name__'. Did you mean: '__ne__'?

运行结果:

python中魔法函数用法总结_第16张图片

13.3 获取模块的名称:

import math

print(math.__name__)
# 输出:"math"

在上述示例中,math.__name__返回模块math的名称。

示例代码:

import math
from flask import Flask


if __name__ == '__main__':
    print(math.__name__)  # 输出:"math"
    print(Flask.__name__)  # 输出:Flask
    

运行结果:

python中魔法函数用法总结_第17张图片

13.4 获取对象的名称:

my_variable = 123

print(my_variable.__name__)
# 抛出AttributeError异常,因为变量没有__name__属性

在上述示例中,由于变量my_variable没有__name__属性,因此访问my_variable.__name__会抛出AttributeError异常。

需要注意的是,__name__属性是一个只读属性,不能通过赋值来改变对象的名称。它主要用于获取对象的名称,例如在调试、日志记录等场景中使用。

14、__class__

        魔法函数__class__是一个特殊的属性,用于获取一个对象所属的类。在Python中,__class__属性可以用于获取对象所属的类的引用。下面是__class__属性的使用详解。

14.1 获取实例所属的类:

class MyClass:
    pass

obj = MyClass()
print(obj.__class__)
# 输出:""

在上述示例中,obj.__class__返回实例obj所属的类MyClass的引用。

14.2 修改实例所属的类:

class ClassA:
    pass

class ClassB:
    pass

obj = ClassA()
print(obj.__class__)
# 输出:""

obj.__class__ = ClassB
print(obj.__class__)
# 输出:""

        在上述示例中,首先创建了一个实例obj,其所属的类是ClassA。然后通过赋值操作obj.__class__ = ClassB,将实例obj的所属类修改为ClassB。最后打印obj.__class__,输出的是""。

需要注意的是,修改实例所属的类仅对该实例有效,不会影响其他实例或类本身的所属关系。

14.3 获取类的父类:

class ParentClass:
    pass

class ChildClass(ParentClass):
    pass

obj = ChildClass()
print(obj.__class__.__bases__)
# 输出:"(,)"

在上述示例中,obj.__class__.__bases__返回类ChildClass的父类ParentClass的元组。如果类有多个父类,则返回所有父类的元组。

示例代码:

class ParentClass(object):
    pass


class ParentClass2(object):
    pass


class ChildClass(ParentClass):
    pass


class ChildClass2(ParentClass, ParentClass2):
    pass


class ChildClass3(ChildClass2):
    pass


if __name__ == '__main__':
    obj = ChildClass()
    print(obj.__class__)
    print(obj.__class__.__base__)
    print(obj.__class__.__bases__)

    print("*" * 100)

    obj2 = ChildClass2()
    print(obj2.__class__)
    print(obj2.__class__.__base__)
    print(obj2.__class__.__bases__)

    print("*" * 100)

    obj3 = ChildClass3()
    print(obj3.__class__)
    print(obj3.__class__.__base__)
    print(obj3.__class__.__bases__)

运行结果:

python中魔法函数用法总结_第18张图片

需要注意的是,__class__属性是一个只读属性,不能通过赋值来改变对象的所属类。它主要用于获取对象所属的类的引用。

详见博文:python中self.__class__的用法详解_IT之一小佬的博客-CSDN博客

15、__module__

        魔法函数__module__是一个特殊的属性,用于获取一个对象所属的模块名称。在Python中,__module__属性可以用于获取对象所属的模块的名称。下面是__module__属性的使用详解。

15.1 获取类或函数所属的模块名称:

# module.py
class MyClass:
    pass

def my_function():
    pass

print(MyClass.__module__)
# 输出:"__main__"

print(my_function.__module__)
# 输出:"__main__"

        在上述示例中,MyClass.__module__返回类MyClass所属的模块的名称,即"__main__"。同样,my_function.__module__返回函数my_function所属的模块的名称,也是"__main__"。

15.2 获取实例所属的模块名称:

# module.py
class MyClass:
    pass

obj = MyClass()
print(obj.__module__)
# 输出:"__main__"

在上述示例中,obj.__module__返回实例obj所属的模块的名称,即"__main__"。

15.3 获取模块中的全局变量所属的模块名称:

# module.py
my_var = 10

print(my_var.__module__)
# 输出:"__main__"

在上述示例中,my_var.__module__返回全局变量my_var所属的模块的名称,也是"__main__"。

需要注意的是,对于内置函数和内置模块,__module__属性的值可能为None,因为这些函数和模块没有明确的所属模块。

__module__属性是一个只读属性,不能通过赋值来改变对象所属的模块。它主要用于获取对象所属的模块的名称。

详见博文:python中__module__模块用法详解_python __module___IT之一小佬的博客-CSDN博客

你可能感兴趣的:(python基础,python,魔法函数)