Python 面向对象 特殊方法(魔法方法)

Python 的特殊方法,两边带双下划线的方法。

比如:__init__(self, ...)、__del__(self)

1、__init__(self,...) : 构造方法

  __init__(self, ...)  构造方法,这个方法在创建对象时,自动触发执行。实例化类格式: 类名() 

class Phone:
    def __init__(self, brand, year):
        self.brand = brand
        self.year = year
        print("执行 __init__ 方法")


p = Phone('小米', 2018)   # 自动执行类中的 __init__ 方法

结果:
执行 __init__ 方法
View Code

2、__del__(self):析构方法

  析构方法,当对象在内存中被释放时,或者手动调用del方法,自动触发执行。

  注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,
    因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。

>>> class Phone:
    def __init__(self, brand, year):
        self.brand = brand
        self.year = year
        print("执行 __init__ 方法")

    def __del__(self):
        print("执行 __del__ 方法")

        
>>> p = Phone('小米', 2018)   # 自动执行类中的 __init__ 方法
执行 __init__ 方法
>>> del p
执行 __del__ 方法
>>> 
View Code

3、__new__(): 定义如何创建对象

  类名() 创建对象时,在自动执行 __init__()方法前,会先执行 object.__new__方法,在内存中开辟对象空间并返回

>>> class Phone:
    def __init__(self, brand, year):
        self.brand = brand
        self.year = year
        print("执行 __init__ 方法")

    def __new__(cls, *args, **kwargs):
        print("执行 __new__ 方法")
        return object.__new__(cls)

    
>>> p = Phone('小米', 2018)   # 自动执行类中的 __init__ 方法
执行 __new__ 方法
执行 __init__ 方法
>>>
1 类名() 执行object.__new__方法,在内存中开辟对象空间并返回;
2 自动执行__init__方法,将对象空间创给self;
3 在__init__给对象封装属性。
View Code
# 单例模式: 一个类只能实例化一个对象
class Phone:
    __instance = None

    def __init__(self, brand, year):
        self.brand = brand
        self.year = year

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


p1 = Phone('小米', 2018)
p2 = Phone('华为', 2017)
p3 = Phone('魅族', 2016)

print(p1)
print(p2)
print(p3)

结果:
<__main__.Phone object at 0x000001C5B2286160>
<__main__.Phone object at 0x000001C5B2286160>
<__main__.Phone object at 0x000001C5B2286160>
View Code

 4、__module__ 和 __class__

  __module__ : 表示当前操作的对象在那个模块,本模块 : __main__

  __class__     : 表示当前操作的对象的类是什么

>>> class Phone:
    def __init__(self, brand, year):
        self.brand = brand
        self.year = year

        
>>> p = Phone('小米', 2018)
>>> p.__module__
'__main__'
>>> p.__class__
<class '__main__.Phone'>
>>> 
View Code

5、__call__

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

>>> class Phone:
    def __init__(self):
        pass
    def __call__(self, *args, **kwargs):
        print('执行 __call__ 方法')

        
>>> p = Phone()
>>> p()
执行 __call__ 方法
>>> 
View Code

6. __dict__

  类或对象中的所有成员

   类的普通字段属于对象;类中的静态字段和方法等属于类:

class Province:

    country = 'China'

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

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

# 获取类的成员,即:静态字段、方法、
print Province.__dict__
# 输出:{'country': 'China', '__module__': '__main__', 'func': <function func at 0x10be30f50>, '__init__': <function __init__ at 0x10be30ed8>, '__doc__': None}

obj1 = Province('河北',10000)
print obj1.__dict__
# 获取 对象obj1 的成员
# 输出:{'count': 10000, 'name': '河北'}

obj2 = Province('河南', 3888)
print obj2.__dict__
# 获取 对象obj2 的成员
# 输出:{'count': 3888, 'name': '河南'}

 7. __str__

  如果一个类中定义了__str__方法,那么在打印 对象 (对象序列化)时,默认输出该方法的返回值。

>>> class Scholar:
	def __str__(self):
		return "富贵不能淫,贫贱不能移,威武不能屈"

	
>>> eagle = Scholar()
>>> print (eagle)
富贵不能淫,贫贱不能移,威武不能屈
>>> 

8、__getitem__、__setitem__、__delitem__

用于索引操作,如字典。以上分别表示获取、设置、删除数据

#!/usr/bin/env python
 
class skill(object):
 
    def __getitem__(self, key):
        print('__getitem__', key)
 
    def __setitem__(self, key, value):
        print('__setitem__', key, value)
 
    def __delitem__(self, key):
        print('__delitem__', key)
 
 
s= skill()
 
talent= s['k1']       # 自动触发执行 __getitem__
s['k2'] = 'swim'      # 自动触发执行 __setitem__
del s['k1']           # 自动触发执行 __delitem__

9. __iter__ 

用于迭代器,之所以列表、字典、元组可以进行for循环,是因为类型内部定义了 __iter__ 

>>> class employees:
	pass
>>> emps = employees()
>>> for emp in emps:
	print(emp)
报错:    for emp in emps: TypeError: 'employees' object is not iterable
>>> class employees:

	def __iter__(self):
		pass
	
>>> emps2 = employees()
>>> for emp in emps2:
	print(emp)

Traceback (most recent call last):
  File "<pyshell#27>", line 1, in <module>
    for emp in emps2:
TypeError: iter() returned non-iterator of type 'NoneType'
>>> 
>>> class fruits:

	def __init__(self, name_list):
		self._name_list = name_list
	def __iter__(self):
		return iter(self._name_list)

>>> apple = fruits(["红富士","嘎拉","黄元帅","红星"])
>>> for i in apple:
	print(i)

红富士
嘎拉
黄元帅
红星
>>> 

以上步骤可以看出,for循环迭代的其实是  iter(["红富士","嘎拉","黄元帅","红星"]) ,所以执行流程可以变更为:

>>> apps = iter(["红富士","嘎拉","黄元帅","红星"])
>>> 
>>> for app in apps:
	print(app)

	
红富士
嘎拉
黄元帅
红星
>>> 
obj = iter(["红富士","嘎拉","黄元帅","红星"])

while True:
    val = obj.next()
    print(val)

For循环语法内部实现
原文地址:https://www.cnblogs.com/51try-again/p/10403577.html