day28---面向对象进阶

1. 内置函数

  • isinstance(obj, Class):检查obj是否是Class类的对象,返回True或False

class A:
        pass
class B(A):
        pass
a = A()
b = B()
c = 1
print(isinstance(a, object))
print(isinstance(b, object))
print(isinstance(c, object))
print(isinstance(a, A))
print(isinstance(a, B))
print(isinstance(b, B))
print(isinstance(b, A))
print(isinstance(c, A))
print(isinstance(c, B))
>>>
True
True
True
True
False
True
True
False
False
# python中所有的类型都属于object类
# 子类实例化的对象,即属于子类,也属于父类
# 父类实例化的对象,只属于父类
  • issubclass(sub, Super):检查sub类是否是Super类的子类,返回True或False

class C:
        pass
class B:
        pass
class A(C):
        pass
print(issubclass(A, object))
print(issubclass(B, object))
print(issubclass(C, object))
print(issubclass(A, B))
print(issubclass(A, C))
print(issubclass(B, C))
print(issubclass(C, A))
>>>
False
True
False
False
True
True
True
# 所有的类都属于object类
# 类的继承只能判断子类属于父类,不能判断父类属于子类
  • vars():以字典的形式返回相关内置方法的键值对

class A:
    pass
print(vars(A))
print(vars())
>>>
{'__module__': '__main__', '__dict__': <attribute '__dict__' of 'A' objects>, '__weakref__': <attribute '__weakref__' of 'A' objects>, '__doc__': None}
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000016102352DA0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:/yange/day28/yan28.py', '__cached__': None, 'A': <class '__main__.A'>}

2. 反射

  • 说明:通过字符串的形式操作对象相关的属性

  • 反射的种类:

    • 对象的反射
    • 类的反射
    • 模块的反射
    • 本模块的反射:sys.modules[__name__]
  • hasattr:用于判断对象是否包含对应的属性

  • getattr:用于返回一个对象属性值;getattr(类名/对象名,'属性名/方法名','不存在时指定的返回值')

  • setattr:设置属性值;setattr(类名/对象名,'属性名/方法名','属性值/方法名')

  • delattr:删除属性,跟del用法一样,从内存中删除;delattr(类名,'属性名/方法名')或delattr(对象名,'属性名')

class Admin:
        role = '管理员'
        def __init__(self, name, age, job):
            self.name = name
            self.age = age
            self.job = job
        def insert(self):
            print('增。。。')
        def update(self):
            print('改。。。')
        def delete(self):
            print('删。。。')
        def select(self):
            print('查。。。')
yy = Admin('丫丫', 18, 'Queen')
yaya_insert = getattr(yy, 'insert')
yaya_update = getattr(yy, 'update')
yaya_delete = getattr(yy, 'delete')
yaya_select = getattr(yy, 'select')
yaya_insert()
yaya_update()
yaya_delete()
yaya_select()
yaya_name = getattr(yy, 'name')
yaya_age = getattr(yy, 'age')
yaya_job = getattr(yy, 'job')
print(yaya_name)
print(yaya_age)
print(yaya_job)
print('-' * 10)
admin = getattr(Admin, 'role')
print(admin)
yaya_aaa = getattr(yy, 'aaa', 'yange')
print(yaya_aaa)
print('-' * 10)
print(hasattr(yy, 'bbb'))
print(hasattr(yy, 'role'))
print(hasattr(yy, 'select'))
print('-' * 10)
setattr(Admin, 'name', 'admin')
print(Admin.name)
setattr(yy, 'sex', '女')
print(yy.sex)
print('-' * 10)
delattr(Admin, 'name')
delattr(yy, 'sex')
print(yy.sex)
>>>
增。。。
改。。。
删。。。
查。。。
丫丫
18
Queen
----------
管理员
yange
----------
False
True
True
----------
admin
女
----------
        print(yy.sex)
AttributeError: 'Admin' object has no attribute 'sex'

3. 常用内置方法

  • __init__():初始化对象

  • __str__()和__repr__():改变对象的字符串显示(如果两者都存在时,优先使用__str__(),只有__str__()不存在时才会使用__repr__())

  • __format__():自定制格式化字符串

  • __del__():析构方法,当对象在内存中被释放时,自动触发执行;析构函数的调用是python解释器在垃圾回收时自动触发执行的

  • __new__():新建实例

  • __call__():对象后面加括号,出发执行;构造方法的执行是创建对象时触发的:对象=类名();__call__()方法的执行是对象后加括号触发的:对象()或类名()()

  • __len__():使用len()函数时调用的方法

  • __hash__():获取hash值

  • __del__():释放对象

  • __cmp__(src,dst):比较src和dst

  • __gt__(self,other):判断self大于other

  • __ge__(self,other):判断self大于或等于other

  • __lt__(self,other):判断self小于other

  • __le__(self,other):判断self小于或等于other

  • __eq__(self,other):判断self等于other

  • __reverse__():使用reversed()函数时调用的方法

  • __contains__():使用in或not in调用的方法

  • item系列:

    • __getitem__():获取键的值
    • __setitem__():设置或新增键值对
    • __delitem__():删除键值对
  • attr系列:

    • __getattr__():获取属性的值
    • __setattr__():设置属性的值
    • __delattr__():删除属性的值
  • __getattribute__():删除属性的值,跟__delattr__()方法功能类似

4. 应用

# 单例模式的简单案例
class Singleton:
        def __new__(cls):
            if not hasattr(cls, '_instance'):
                cls._instance = object.__new__(cls)
            return cls._instance
one = Singleton()
two = Singleton()
two.a = 3
print(one.a)
print(id(one))
print(id(two))
print(one == two)
print(one is two)
>>>
3
2158822532208
2158822532208
True
True
# 扑克牌发牌高级代码
from collections import namedtuple
Card = namedtuple('Card', ['rank', 'suit'])
class FranchDeck:
        ranks = [str(n) for n in range(2,11)] + list('JQKA')
        suits = ['梅花', '方片', '红桃', '黑桃']
        def __init__(self):
            self._cards = [Card(rank, suit) for rank in FranchDeck.ranks for suit in FranchDeck.suits]
        def __len__(self):
            return len(self._cards)
        def __getitem__(self, item):
            return self._cards[item]
deck = FranchDeck()
print(deck[0])
import random
for i in range(20):
    print(random.choice(deck))
>>>
Card(rank='2', suit='梅花')
Card(rank='9', suit='红桃')
Card(rank='7', suit='黑桃')
Card(rank='10', suit='方片')
Card(rank='K', suit='梅花')
Card(rank='4', suit='红桃')
Card(rank='2', suit='方片')
Card(rank='8', suit='梅花')
Card(rank='9', suit='黑桃')
Card(rank='Q', suit='梅花')
Card(rank='2', suit='红桃')
Card(rank='5', suit='方片')
Card(rank='6', suit='黑桃')
Card(rank='4', suit='红桃')
Card(rank='3', suit='黑桃')
Card(rank='9', suit='红桃')
Card(rank='5', suit='方片')
Card(rank='3', suit='方片')
Card(rank='2', suit='方片')
Card(rank='3', suit='红桃')
Card(rank='2', suit='方片')
# 扑克牌洗牌高级代码
from collections import namedtuple
Card = namedtuple('Card', ['rank', 'suit'])
class FranchDeck:
        ranks = [str(n) for n in range(2,11)] + list('JQKA')
        suits = ['梅花', '方片', '红桃', '黑桃']
        def __init__(self):
            self._cards = [Card(rank, suit) for rank in FranchDeck.ranks for suit in FranchDeck.suits]
        def __len__(self):
            return len(self._cards)
        def __getitem__(self, item):
            return self._cards[item]
deck = FranchDeck()
import random
print(deck._cards)
print('-' * 115)
random.shuffle(deck._cards)
print(deck._cards)
>>>
[Card(rank='2', suit='梅花'), Card(rank='2', suit='方片'), Card(rank='2', suit='红桃'), Card(rank='2', suit='黑桃'), Card(rank='3', suit='梅花'), Card(rank='3', suit='方片'), Card(rank='3', suit='红桃'), Card(rank='3', suit='黑桃'), Card(rank='4', suit='梅花'), Card(rank='4', suit='方片'), Card(rank='4', suit='红桃'), Card(rank='4', suit='黑桃'), Card(rank='5', suit='梅花'), Card(rank='5', suit='方片'), Card(rank='5', suit='红桃'), Card(rank='5', suit='黑桃'), Card(rank='6', suit='梅花'), Card(rank='6', suit='方片'), Card(rank='6', suit='红桃'), Card(rank='6', suit='黑桃'), Card(rank='7', suit='梅花'), Card(rank='7', suit='方片'), Card(rank='7', suit='红桃'), Card(rank='7', suit='黑桃'), Card(rank='8', suit='梅花'), Card(rank='8', suit='方片'), Card(rank='8', suit='红桃'), Card(rank='8', suit='黑桃'), Card(rank='9', suit='梅花'), Card(rank='9', suit='方片'), Card(rank='9', suit='红桃'), Card(rank='9', suit='黑桃'), Card(rank='10', suit='梅花'), Card(rank='10', suit='方片'), Card(rank='10', suit='红桃'), Card(rank='10', suit='黑桃'), Card(rank='J', suit='梅花'), Card(rank='J', suit='方片'), Card(rank='J', suit='红桃'), Card(rank='J', suit='黑桃'), Card(rank='Q', suit='梅花'), Card(rank='Q', suit='方片'), Card(rank='Q', suit='红桃'), Card(rank='Q', suit='黑桃'), Card(rank='K', suit='梅花'), Card(rank='K', suit='方片'), Card(rank='K', suit='红桃'), Card(rank='K', suit='黑桃'), Card(rank='A', suit='梅花'), Card(rank='A', suit='方片'), Card(rank='A', suit='红桃'), Card(rank='A', suit='黑桃')]
-------------------------------------------------------------------------------------------------------------------
[Card(rank='5', suit='黑桃'), Card(rank='5', suit='方片'), Card(rank='J', suit='方片'), Card(rank='6', suit='梅花'), Card(rank='8', suit='黑桃'), Card(rank='2', suit='黑桃'), Card(rank='9', suit='黑桃'), Card(rank='K', suit='黑桃'), Card(rank='A', suit='梅花'), Card(rank='A', suit='黑桃'), Card(rank='10', suit='红桃'), Card(rank='5', suit='红桃'), Card(rank='6', suit='方片'), Card(rank='K', suit='梅花'), Card(rank='3', suit='方片'), Card(rank='2', suit='红桃'), Card(rank='A', suit='方片'), Card(rank='Q', suit='梅花'), Card(rank='7', suit='梅花'), Card(rank='10', suit='梅花'), Card(rank='7', suit='红桃'), Card(rank='Q', suit='黑桃'), Card(rank='A', suit='红桃'), Card(rank='4', suit='方片'), Card(rank='J', suit='梅花'), Card(rank='3', suit='梅花'), Card(rank='5', suit='梅花'), Card(rank='K', suit='红桃'), Card(rank='K', suit='方片'), Card(rank='9', suit='梅花'), Card(rank='J', suit='红桃'), Card(rank='7', suit='黑桃'), Card(rank='9', suit='方片'), Card(rank='3', suit='黑桃'), Card(rank='4', suit='黑桃'), Card(rank='2', suit='方片'), Card(rank='10', suit='黑桃'), Card(rank='Q', suit='红桃'), Card(rank='7', suit='方片'), Card(rank='8', suit='方片'), Card(rank='4', suit='梅花'), Card(rank='2', suit='梅花'), Card(rank='6', suit='红桃'), Card(rank='6', suit='黑桃'), Card(rank='3', suit='红桃'), Card(rank='9', suit='红桃'), Card(rank='8', suit='红桃'), Card(rank='Q', suit='方片'), Card(rank='J', suit='黑桃'), Card(rank='10', suit='方片'), Card(rank='4', suit='红桃'), Card(rank='8', suit='梅花')]
# 面试题
# 一个类有100个对象,每一个对象都拥有三个属性:name,sex,age
# 如果两个对象的name和sex属性完全一致,就认为是同一个对象
# 请对这100个对象进行去重
class Person:
    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex
    def __hash__(self):
        return hash(self.name+self.sex)
    def __eq__(self, other):
        if self.name == other.name and self.sex == other.sex:return True
p_lst = []
for i in range(100):
    p_lst.append(Person('egon',i,'male'))
print(p_lst)
print(set(p_lst))
>>>
[<__main__.Person object at 0x0000026B1E8CA550>, <__main__.Person object at 0x0000026B1E8CA588>, <__main__.Person object at 0x0000026B1E8CA5C0>, <__main__.Person object at 0x0000026B1E8CA5F8>, <__main__.Person object at 0x0000026B1E8CA630>, <__main__.Person object at 0x0000026B1E8CA668>, <__main__.Person object at 0x0000026B1E8CA6A0>, <__main__.Person object at 0x0000026B1E8CA6D8>, <__main__.Person object at 0x0000026B1E8CA710>, <__main__.Person object at 0x0000026B1E8CA748>, <__main__.Person object at 0x0000026B1E8CA780>, <__main__.Person object at 0x0000026B1E8CA7B8>, <__main__.Person object at 0x0000026B1E8CA7F0>, <__main__.Person object at 0x0000026B1E8CA828>, <__main__.Person object at 0x0000026B1E8CA860>, <__main__.Person object at 0x0000026B1E8CA898>, <__main__.Person object at 0x0000026B1E8CA8D0>, <__main__.Person object at 0x0000026B1E8CA908>, <__main__.Person object at 0x0000026B1E8CA940>, <__main__.Person object at 0x0000026B1E8CA978>, <__main__.Person object at 0x0000026B1E8CA9B0>, <__main__.Person object at 0x0000026B1E8CA9E8>, <__main__.Person object at 0x0000026B1E8CAA20>, <__main__.Person object at 0x0000026B1E8CAA58>, <__main__.Person object at 0x0000026B1E8CAA90>, <__main__.Person object at 0x0000026B1E8CAAC8>, <__main__.Person object at 0x0000026B1E8CAB00>, <__main__.Person object at 0x0000026B1E8CAB38>, <__main__.Person object at 0x0000026B1E8CAB70>, <__main__.Person object at 0x0000026B1E8CABA8>, <__main__.Person object at 0x0000026B1E8CABE0>, <__main__.Person object at 0x0000026B1E8CAC18>, <__main__.Person object at 0x0000026B1E8CAC50>, <__main__.Person object at 0x0000026B1E8CAC88>, <__main__.Person object at 0x0000026B1E8CACC0>, <__main__.Person object at 0x0000026B1E8CACF8>, <__main__.Person object at 0x0000026B1E8CAD30>, <__main__.Person object at 0x0000026B1E8CAD68>, <__main__.Person object at 0x0000026B1E8CADA0>, <__main__.Person object at 0x0000026B1E8CADD8>, <__main__.Person object at 0x0000026B1E8CAE10>, <__main__.Person object at 0x0000026B1E8CAE48>, <__main__.Person object at 0x0000026B1E8CAE80>, <__main__.Person object at 0x0000026B1E8CAEB8>, <__main__.Person object at 0x0000026B1E8CAEF0>, <__main__.Person object at 0x0000026B1E8CAF28>, <__main__.Person object at 0x0000026B1E8CAF60>, <__main__.Person object at 0x0000026B1E8CAF98>, <__main__.Person object at 0x0000026B1E8CAFD0>, <__main__.Person object at 0x0000026B1E8CD048>, <__main__.Person object at 0x0000026B1E8CD080>, <__main__.Person object at 0x0000026B1E8CD0B8>, <__main__.Person object at 0x0000026B1E8CD0F0>, <__main__.Person object at 0x0000026B1E8CD128>, <__main__.Person object at 0x0000026B1E8CD160>, <__main__.Person object at 0x0000026B1E8CD198>, <__main__.Person object at 0x0000026B1E8CD1D0>, <__main__.Person object at 0x0000026B1E8CD208>, <__main__.Person object at 0x0000026B1E8CD240>, <__main__.Person object at 0x0000026B1E8CD278>, <__main__.Person object at 0x0000026B1E8CD2B0>, <__main__.Person object at 0x0000026B1E8CD2E8>, <__main__.Person object at 0x0000026B1E8CD320>, <__main__.Person object at 0x0000026B1E8CD358>, <__main__.Person object at 0x0000026B1E8CD390>, <__main__.Person object at 0x0000026B1E8CD3C8>, <__main__.Person object at 0x0000026B1E8CD400>, <__main__.Person object at 0x0000026B1E8CD438>, <__main__.Person object at 0x0000026B1E8CD470>, <__main__.Person object at 0x0000026B1E8CD4A8>, <__main__.Person object at 0x0000026B1E8CD4E0>, <__main__.Person object at 0x0000026B1E8CD518>, <__main__.Person object at 0x0000026B1E8CD550>, <__main__.Person object at 0x0000026B1E8CD588>, <__main__.Person object at 0x0000026B1E8CD5C0>, <__main__.Person object at 0x0000026B1E8CD5F8>, <__main__.Person object at 0x0000026B1E8CD630>, <__main__.Person object at 0x0000026B1E8CD668>, <__main__.Person object at 0x0000026B1E8CD6A0>, <__main__.Person object at 0x0000026B1E8CD6D8>, <__main__.Person object at 0x0000026B1E8CD710>, <__main__.Person object at 0x0000026B1E8CD748>, <__main__.Person object at 0x0000026B1E8CD780>, <__main__.Person object at 0x0000026B1E8CD7B8>, <__main__.Person object at 0x0000026B1E8CD7F0>, <__main__.Person object at 0x0000026B1E8CD828>, <__main__.Person object at 0x0000026B1E8CD860>, <__main__.Person object at 0x0000026B1E8CD898>, <__main__.Person object at 0x0000026B1E8CD8D0>, <__main__.Person object at 0x0000026B1E8CD908>, <__main__.Person object at 0x0000026B1E8CD940>, <__main__.Person object at 0x0000026B1E8CD978>, <__main__.Person object at 0x0000026B1E8CD9B0>, <__main__.Person object at 0x0000026B1E8CD9E8>, <__main__.Person object at 0x0000026B1E8CDA20>, <__main__.Person object at 0x0000026B1E8CDA58>, <__main__.Person object at 0x0000026B1E8CDA90>, <__main__.Person object at 0x0000026B1E8CDAC8>, <__main__.Person object at 0x0000026B1E8CDB00>, <__main__.Person object at 0x0000026B1E8CDB38>]
{<__main__.Person object at 0x0000026B1E8CA550>}
posted @ 2017-11-24 20:32  _岩哥  阅读(106)  评论(0)    收藏  举报