isinstance和issubclass

isinstance(obj,cls)检查是否obj是否是类 cls 的对象

class Foo(object):
     pass
  
obj = Foo()
  
isinstance(obj, Foo)

issubclass(sub, super)检查sub类是否是 super 类的派生类 

class Foo(object):
    pass
 
class Bar(Foo):
    pass
 
issubclass(Bar, Foo)

反射

反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。

python面向对象中的反射:通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)

class A:
    def func(self):
        print('in func')

a = A()
a.name = 'alex'
a.age = 63
ret = getattr(a,'name') #通过变量名的字符串形式取到的值

sss = input('>>>')
print(getattr(a,sss))
class A:
    def func(self):
        print('in func')

a = A()
a.name = 'alex'
a.age = 63
#反射对象的方法
ret = getattr(a,'func')
ret()
class Foo:
    f = '类的静态变量'
    def __init__(self,name,age):
        self.name=name
        self.age=age

    def say_hi(self):
        print('hi,%s'%self.name)

obj=Foo('egon',73)

#检测是否含有某属性
print(hasattr(obj,'name'))
print(hasattr(obj,'say_hi'))

#获取属性
n=getattr(obj,'name')
print(n)
func=getattr(obj,'say_hi')
func()

print(getattr(obj,'aaaaaaaa','不存在啊')) #报错

#设置属性
setattr(obj,'sb',True)
setattr(obj,'show_name',lambda self:self.name+'sb')
print(obj.__dict__)
print(obj.show_name(obj))

#删除属性
delattr(obj,'age')
delattr(obj,'show_name')
delattr(obj,'show_name111')#不存在,则报错

print(obj.__dict__)
#导入当前模块
import sys


def s1():
    print 's1'


def s2():
    print 's2'


this_module = sys.modules[__name__]

hasattr(this_module, 's1')
getattr(this_module, 's2')

#导入模块也可以反射
def test():
    print('from the test')
"""
程序目录:
    module_test.py
    index.py
 
当前文件:
    index.py
"""

import module_test as obj

#obj.test()

print(hasattr(obj,'test'))

getattr(obj,'test')()

__str__和__repr__

内置的类方法和内置的函数之间有千丝万缕的联系

改变对象的字符串显示__str__,__repr__

自定制格式化字符串__format__

class A:
    def __str__(self):
        return "A's object"
a = A()

print(a)  #a.__str__ #打印一个对象的时候,就是调用a.__str__
'''
object里有一个__str__,一旦被调用,就返回调用这个方法的对象地址
%s str() 直接打印 实际上都是走的__str__
%r repr() 实际上都是走的__repr__
repr 是str的备胎,但str不能做repr的备胎
srt(obj)的时候,实际上是内部调用了obj.__str__方法,如果str方法
有,那么他返回的必定是一个str类型,如果没有__str__方法,会先找本类中的__repr__方法,再没有再找父类中的__str__
repr(),只会找__repr__,如果没有找父类的
'''
class B:

     def __str__(self):
         return 'str : class B'

     def __repr__(self):
         return 'repr : class B'


b=B()
print('%s'%b)
print('%r'%b)
'''
str函数或者print函数--->obj.__str__()
repr或者交互式解释器--->obj.__repr__()
如果__str__没有被定义,那么就会使用__repr__来代替输出
注意:这俩方法的返回值必须是字符串,否则抛出异常
'''

__del__

class Foo:

    def __del__(self):
        print('执行我啦') 

f1=Foo()
del f1
print('------->')

析构方法,当对象在内存中被释放时,自动触发执行,先执行后删除。

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

__len__

内置的方法有很多
不一定全都在object中
class A:
    def __init__(self):
        self.a = 1
        self.b = 2

    def __len__(self):
        return len(self.__dict__)
a = A()
print(len(a))

class B:
    def __len__(self):
        return 10
b= B()
print(len(b))

__call__

class Foo:

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

        print('__call__')


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

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

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

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('zack',38,'')
print(f['name'])
f['hobby'] = ''
print(f.hobby,f['hobby'])
del f.hobby  #object 原生支持 __delattr__
del f['hobby']  #通过自己实现的 
print(f.__dict__)

__new__

#init是初始化方法,__new__是构造方法:创建一个对象
class A:
    def __init__(self):
        self.x = 1
        print('in init function')
    def __new__(cls,*args,**kwargs):
        print('in new function')
        return object.__new__(A,*args,**kwargs)
a = A()
print(a,x)
'''
设计模式
单例模式:一个类始终只有一个实例
当你第一次实例化这个类的时候 就创建一个实例化的对象
当你之后再来实例化的时候 就用之前的创建的对象
'''
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__(A)
        return cls.__instance

e = A('egg',38)
z = A('zack',25)
print(egg)
print(zack)

__eq__

class A:
    def __init__(self,name):
        self.name = name
    def __eq__(self,other):
        if self.__dict__ == other.__dict__:
            return True
        else:
            return False
            
obj1 = A('egg')
obj2 = A('egg')
print(obj1 == obj2)

__hash__

class A:
    def __init__(self):
        self.a = 1
        self.b = 2

    def __hash__(self):
        return hash(str(self.a)+str(self.b))
a = A()
print(hash(a))
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

deck = FranchDeck()
print(deck[0])
from random import choice
print(choice(deck))
print(choice(deck))

from random import shuffle
shuffle(deck)
print(deck[:5])
纸牌游戏
'''
有一个类的init方法如下:
class Person:
    def __init__(self,name,age,sex,weight):
        self.name = name
        self.sex = sex
        self.age = age
        self.weight = weight
假设有100个person的对象,
若两个对象的obj1,obj2的name和sex属性相同
即obj1.name==obj2.name and obj1.sex==obj2.sex
我们认为两个对象为同一个对象,已知一个列表中的100个对象,对这100个对象进行去重。
提示:
    重写Person类重的两个内置方法
'''
class Person:
    def __init__(self,name,age,sex,weight):
        self.name = name
        self.sex = sex
        self.age = age
        self.weight = weight
    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)

person = Person('sole',20,'',80)
person1 = Person('sole',21,'',80)
print(set((person,person1)))    
去重

 

posted on 2018-01-22 15:40  Kindergarten_Panda  阅读(83)  评论(0编辑  收藏  举报