面向对象进阶(二)

1、__del__方法:删除一个对象时调用的方法

import time
class A:
    def __init__(self):
        self.f = open('userinfo','a')
    def consume(self):
        pass
    def __del__(self):
        '''在删除一个对象之前做一些收尾工作'''
        self.f.close()
        print('删除一个对象的时候调用我')
a = A()
time.sleep(1)
del a
# 删除一个对象的时候,如果内部存在__del__方法,
# 那么在删除一个对象之前先执行__del__方法中的代码
print(a)

2、__new__构造方法:构造一个新的对象

class A:
    def __init__(self,name,age):
        self.name = name
        self.age = age
        print('执行了__init__方法')
    def __new__(cls, *args, **kwargs):
        print('执行了__new__方法')
        return object.__new__(cls)    #创造对象,将对象返回
a = A('xxx','22')
print(type(a))
print(type(A))
先执行__new__方法,创造一个对象
然后把创造处的对象传递给__init__方法
会把self自动返回,被a接收

3、元类type():创造类的类   所有直接用class创建出来的类的元类都是type

# class 类名(B,classMeta=元类名)
# class 类名(B,classMeat = type)   #默认
# 元类  创造  类     所以  所有的类的type都是他的元类,默认他是type
# 类  创造对  象     所以  具有创造对象的方法__init__的方法,所有的对象的type都是他的类
# class B(A):
#     pass
# print(type(B))

4、单例模式:一个类 可以被多次实例化,但同一时间在python中,只能有一个实例

# class A:
#     _instance = None
#     def __init__(self,name):
#         self.name = name
#     def __new__(cls, *args, **kwargs):
#         if not A._instance:
#             A._instance = object.__new__(cls)
#         return A._instance
# a1 = A('alex')
# # print(a1.name)
# a2 = A('egon')
# print(a1.name,a2.name)
#使用反射来实现
# class A:
#     def __init__(self,name):
#         self.name = name
#     def __new__(cls, *args, **kwargs):
#         if not hasattr(A,'_instance'):
#             A._instance = object.__new__(cls)
#         return A._instance
# a1 = A('alex')
# # print(a1.name)
# a2 = A('egon')
# print(a1.name,a2.name)

5、item系列:__getitem__\__setitem__\__delitem__

class A:
    def __init__(self,name):
        self.name = name
        self.age = 21
    def __getitem__(self, item):
        return self.__dict__[item]
    def __setitem__(self, key, value):
        self.__dict__[key] = value
    def __delitem__(self, key):
        del self.__dict__[key]
a = A('dzf')
# print(a['name'])    #对应了类中的一个方法
# print(a['age'])     #对应了类中的一个方法
a['sex'] = 'boy'     #对应 __setitem__方法,增加,修改一个对象
print(a.sex)
print(a['sex'])
# a['sex'] = 'girl'
# print(a.__dict__)
# del a['name']      #对应 __delitem__  删除一个对象
# print(a.__dict__)

6、__call__:

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

注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()

class Foo:

    def __init__(self):
        pass
    
    def __call__(self, *args, **kwargs):

        print('__call__')

obj = Foo() # 执行 __init__
obj()       # 执行 __call__

7、__hash__方法:可哈希的数据类型都是不可变数据类型

# class A:
#     def __hash__(self):
#         return 666
#
# a = A()
# b = A()
# print(hash(a))      #objet.__hash__()
# print(hash(b))     #objet.__hash__()

# dict 的 key  set 的 元素  都必须是可哈希的
# hash(objet)函数,objet对象对应的类必然内部实现了__hash__方法
# hash的结果就是__hash__方法的返回值
# 且在一次成的执行过程中是不会发生变化的
# 且要想作为字典的key或者作为集合的元素,这个对象对应的类必须实现__hash__方法
View Code

8、面试题

# 金融公司面试题
# 有一个类,对应这个类产生了100个对象
# 每个对象有三个属性 : 姓名 年龄 性别
# 请对这一百个对象进行去重,如果姓名和性别相同,即便年龄不同也是相同的对象
# 问最简便的方法?
class Person:
    def __init__(self,name,sex,age):
        self.name = name
        self.sex = sex
        self.age = age
    def __hash__(self):
        return hash('%s%s'%(self.name,self.sex))
    def __eq__(self, other):
        if self.name == other.name  and self.sex == other.sex:
            return True
l = []
for i in range(100):
    l.append(Person('alex','man',i))
print(set(l))
# 去重在函数内部先执行了__hash__方法,判断hash值是否相等,然后执行了__eq__方法,判断值是否相等

9、纸牌例子:

from collections import namedtuple    #每个可命名元组都是没有方法的类
Card =namedtuple('Card',['rank','suit'])
# card1 =Card(1,'方块')
# print(card1)
class FranchDeck:
    ranks = [str(n) for n in range(2,11)] + list('JQKA')
    suit = ['红心','方片','黑桃','梅花']
    def __init__(self):
        self._cards = [Card(rank,suit) for rank in FranchDeck.ranks
                                       for suit in FranchDeck.suit]   # 列表生成式
    def __len__(self):         #内置发方法
        return len(self._cards)
    def __getitem__(self, item):       #内置发方法
        return self._cards[item]
    def __setitem__(self, key, value):       #内置发方法
        self._cards[key] = value
deak = FranchDeck()
# print(deak[:])
from random import choice     #随机抽取一张拍
choice(deak)
print(deak[2])
from random import shuffle    #洗牌
shuffle(deak)
print(deak[:]

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  

 

posted @ 2018-03-13 18:13  临丶  阅读(56)  评论(0)    收藏  举报