面向对象(二)

isinstance和issubclass

isinstance(a,b)检查是否a是b的对象

class Func:
    pass
s = Func()
print(isinstance(s,Func))

issubclass(a,b)检查a类是否是b类的派生类

class Func:
    pass
class Bar(Func):
    pass
issubclass(Bar,Func)

反射

  通过字符串的形式操作对象相关的属性。(python一切事物都是对象,所以都可以反射)

getattr(对象,'属性')

class A:
    def __init__(self,name):
        self.name = name
    def func(self):
        print('in func')
a = A('wahaha')
ret = getattr(a,'name')
print(ret)

hasattr(判断成立后执行getattr,没有不会报错)

class A:
    def __init__(self,name):
        self.name = name
    def func(self):
        print(self.name)
a = A('alex')
s = input('>>>')
if hasattr(a,s):
    getattr(a,s)()

setattr添加一个属对象属性

class A:
    pass
a = A()
setattr(a,'name','sss')
print(a.name)

delattr 删除一个类和属性,如果自己没有就去父类找

class A:
    pass
a = A()
setattr(a,'name','sss')
setattr(A,'name','aaa')
delattr(a,'name')
print(a.name)

内置用法:

class Teacher:
    def __init__(self,name,salary):
        self.name = name
        self.salary = salary
    def __str__(self):
        return "hello%s"%self.name
    def __repr__(self):
        return str(self.__dict__)
    def func(self):
        return 'hahaha'
h = Teacher('姓名',250)
print(h)
print(repr(h))

%s str() 直接打印 执行的是__str__

%r repr() 执行的__repr

repr是str的备胎,但str不能做repr的备胎

print和%s打印时默认打印__str__ 方法,一定返回字符串,如果没有打印 __repr__方法

  str顺序:

    没有父类:类  ---> str ---> repr ---> 父类object ---> str ---> repr

    有父类:类 ---> str --->父类str ---> repr ---> 父类的repr ---> object类

析构函数

  __del__  删除并执行

class A:
     def __del__(self):   # 析构函数: 在删除一个对象之前进行一些收尾工作
        self.f.close()
a = A()
a.f = open()   # 打开文件 第一 在操作系统中打开了一个文件 拿到了文件操作符存在了内存中
del a          # a.f 拿到了文件操作符消失在了内存中,del 既执行了这个方法,又删除了变量

 执行类时,默认执行__call__函数

class A:
    def __init__(self,name):
        self.name = name
    def __call__(self):
        for k in self.__dict__:
            print(k,self.__dict__[k])
a = A('alex')()

__len__ 计算长度

class A:
    def __init__(self):
        self.a = 1
        self.b = 2
    def __len__(self):
        return len(self.__dict__)
a = A()
print(len(a))

__item__方法

class Foo:
    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex
    def __getitem__(self, item):
        if hasattr(self,item):
            return self.__dict__[item]
    def __setitem__(self, key, value):
        self.__dict__[key] = value
    def __delitem__(self, key):
        del self.__dict__[key]

f = Foo('alex',88,'')
print(f['name'])
f['hobby'] = ''
print(f.hobby,f['hobby'])
del f.hobby
del f['hobby']
print(f.__dict__)

__getitem__ :可以用f['name']方法查找内容,用字符方法

__setitem__:可以添加key和value

__delitem__:可以del f['hobby'] 删除,但是一定要有__delitem__

__new__:先执行new,然后再执行init,优先级最高。

class A:
    def __init__(self):
        self.x = 1
        print('in init ')
    def __new__(cls, *args, **kwargs):
        print('in new')
        return object.__new__(A)
a1 = A()
a2 = A()
print(a1)
print(a2)
print(a1.x)

 设计模块: 

  一共有23种

  单例模式:一个类,始终只有一个实例,当你第一次实例化这个类的时候就创建一个实例化的对象,当你之后再来实例化的时候,就用之前创建的对象。

class A:
    __instance = False
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def __new__(cls, *args, **kwargs):
        if cls.__instance:
            return cls.__instance
        cls.__instance = object.__new__(cls)
        return cls.__instance
egon = A('egon',38)
egon.cloth = '小花袄'
nezha = A('nezha',25)
print(nezha.name)
print(egon.name)
print(nezha.cloth)

__eq__:在比较时候(==)会在类里找有没有__eq__,如果有就是字符串比较,如果没有就比较的是内存地址。

class A:
    def __init__(self,name):
        self.name = name
    def __eq__(self, other):
        if self.__dict__ == other.__dict__:
            return True
        else:
            return False
a1 = A('egon')
a2 = A('egon')
print(a1 == a2)

__hash__:每次执行值都不一样。

class A:
    def __init__(self,name,sex):
        self.name = name
        self.sex = sex
    def __hash__(self):
        return hash(self.name+self.sex)
a = A('eggon','')
b = A('eggon','')
print(hash(a))
print(hash(b))

去重,去如果name,sex相同就去重。

class A:
    def __init__(self,name,sex,age):
        self.name = name
        self.sex = sex
        self.age = age
    def __eq__(self, other):
        if self.name == other.name and self.sex == other.sex:
            return True
        return False
    def __hash__(self):
        return hash(self.name+self.sex)
a = A('egg','',38)
b = A('egg','',37)
print(set((a,b)))

随机抽牌

import json
from collections import namedtuple
from random import choice
from random import shuffle

Card = namedtuple('Card',['rank','suit'])  #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]

    def __setitem__(self, key, value):
        self._cards[key] = value
    def __str__(self):
        return json.dump(self._cards,ensure_ascii=False)

deck = FranchDeck()
print(choice(deck))  #随机选一张
shuffle(deck)      #洗牌
print(deck[:10])
原文地址:https://www.cnblogs.com/tsboy/p/8329736.html