Python魔术方法

魔法属性

无论人或事物往往都有不按套路出牌的情况,Python的类属性也是如此,存在着一些具有特殊含义的属性,详情如下:

1. doc

  • 表示类的描述信息
class Foo:
    """Foo描述类信息"""

    def func(self):
        pass


print(Foo.__doc__)  # Foo类的描述信息

2. moduleclass

  • module 表示当前操作的对象在那个模块
  • class 表示当前操作的对象的类是什么

test.py

class Person(object):
    def __init__(self):
        self.name = 'xx'

main.py

from test import Person

obj = Person()
print(obj.__module__)  # test
print(obj.__class__)  # 

3. init

  • 初始化方法,通过类创建对象时,自动触发执行
class Person:
    def __init__(self, name):
        self.name = name
        self.age = 18


obj = Person('lp')  # 自动执行类中的 __init__ 方法

4. del

  • 定义了当对象被垃圾回收时的行为
  • 一般无须定义,当对象在内存中被释放时,自动触发执行c此方法
  • 并非实现了语句 del x (因此该语句不等同于 x.__del__())
  • 当Python解释器退出但对象仍然存活的时候, __del__ 并不会执行
class Foo:
    def __del__(self):
        pass

5. call

  • 对象后面加括号,触发执行。

  • __init__方法的执行是由创建对象触发的,即:对象 = 类名()

  • call 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()

  • 在某些需要经常改变状态的类的实例中显得特别有用

class Entity:
        '''表示一个实体的类,调用它的实例
        可以更新实体的位置'''

        def __init__(self, size, x, y):
            	print('__init__')
                self.x, self.y = x, y
                self.size = size

        def __call__(self, x, y):
                '''改变实体的位置'''
                print('__call__')
                self.x, self.y = x, y


obj = Foo(1,2)  # 执行 __init__
obj(3,4)  # 执行 __call__

6. dict

  • 类或对象中的所有属性
  • 类的实例属性属于对象
  • 类中的类属性和方法等属于类
class Province(object):
    country = 'China'

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

    def func(self, *args, **kwargs):
        print('func')

# 获取类的属性,即:类属性、方法、
print(Province.__dict__)
# 输出:{'__dict__': , '__module__': '__main__', 'country': 'China', '__doc__': None, '__weakref__': , 'func': , '__init__': }

obj1 = Province('山东', 10000)
print(obj1.__dict__)
# 获取 对象obj1 的属性
# 输出:{'count': 10000, 'name': '山东'}

obj2 = Province('山西', 20000)
print(obj2.__dict__)
# 获取 对象obj1 的属性
# 输出:{'count': 20000, 'name': '山西'}

7. str or repr

  • 如果一个类中定义了__str__方法,那么在打印 对象时,默认输出该方法的返回值。
  • str() 和 repr() 最主要的差别在于“目标用户”。repr() 的作用是产生机器可读的输出(大部分情况下,其输出可以作为有效的Python代码),而 str() 则产生人类可读的输出
class Foo:
    def __str__(self):
        return 'laowang'


obj = Foo()
print(obj)
# 输出:laowang

8.getitem,setitem,delitem

  • 用于索引操作,如字典,列表。以上分别表示获取、设置、删除数据
# -*- coding:utf-8 -*-


class Foo(object):
    def __init__(self, values=None):
        if values is None:
            self.values = {}
        else:
            self.values = values

    def __getitem__(self, key):

        # 如果键的类型或值不合法,列表会返回异常
        print('__getitem__', key)
        return self.values[key]

    def __setitem__(self, key, value):
        print('__setitem__', key, value)
        self.values[key] = value

    def __delitem__(self, key):
        print('__delitem__', key)
        del self.values[key]

    def __iter__(self):
        return iter(self.values)


obj = Foo()
obj['k1'] = 'tangsan'  # 自动触发执行 __setitem__
result = obj['k1']  # 自动触发执行 __getitem__
del obj['k1']  # 自动触发执行 __delitem__

9.getslice,setslice,delslice

  • 该三个方法用于分片操作,如:列表
# -*- coding:utf-8 -*-

class Foo(object):

    def __getslice__(self, i, j):
        print('__getslice__', i, j)

    def __setslice__(self, i, j, sequence):
        print('__setslice__', i, j)

    def __delslice__(self, i, j):
        print('__delslice__', i, j)

obj = Foo()

obj[-1:1]                   # 自动触发执行 __getslice__
obj[0:1] = [11,22,33,44]    # 自动触发执行 __setslice__
del obj[0:2]                # 自动触发执行 __delslice__

10.iter,next

from collections.abc import Iterator

class Array:
    index = 0
    mylist = [0,1,2]

    # 返回该对象的迭代器类的实例
    # 因为自己就是迭代器,所以返回self
    def __iter__(self):
        return self

    # 当无元素时,必要抛出 StopIteration
    def __next__(self):
        if self.index <= len(self.mylist)-1:
            value = self.mylist[self.index]
            self.index += 1
            return value
        raise StopIteration

my_iterator = iter(Array())
print(isinstance(my_iterator, Iterator)) # output: True
print(next(my_iterator))  # output: 0
print(next(my_iterator))  # output: 1
print(next(my_iterator))  # output: 2
print(next(my_iterator))  # StopIteration

11.exit,enter

class Resource():
    def __enter__(self):
        print('===connect to resource===')
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('===close resource connection===')
        return True

    def operate(self):
        1/0

with Resource() as res:
    res.operate()

12. new

  • 对象实例化时第一个调用的方法,它只取下 cls 参数,并把其他参数传给 __init__
  • 适用于类继承自一个像元组或者字符串这样不经常改变的类型的时候
class Singleton:
    instance = {}

    def __new__(cls, *args, **kwargs):
        if cls not in cls.instance:
            cls.instance[cls] = cls

        return cls.instance[cls]

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


s1 = Singleton('1')
s2 = Singleton('2')
print(id(s1) == id(s2))

你可能感兴趣的:(1.python进阶,python,pycharm,flask)