python--面向對象進階

isinstance和issubclass

1.isinstance(obj,cls)檢查是否obj是不是類 cls 的對象python

#!/usr/bin/env python
# -*- coding:utf-8 -*-
class Foo:
    pass
obj = Foo()
print(isinstance(obj,Foo))

2.issubclass(cls,cls)檢查Bar是不是Foo的派生類app

#!/usr/bin/env python
# -*- coding:utf-8 -*-
class Foo(object):
    pass
class Bar(Foo):
    pass

print(issubclass(Bar,Foo))

反射

1.反射:
反射的概念是由Smith在1982年首次提出的,主要是指程序能夠訪問、檢測和修改它自己狀態或行爲的一種能力(自省)。這一律唸的提出很快引起了計算機科學領域關於應用反射性的研究。它首先被程序語言的設計領域所採用,並在Lisp和麪向對象方面取得了成績。
2.python面向對象中的反射:經過字符串的形式操做對象相關的屬性。python中的一切事物都是對象(均可以使用反射)四個能夠實現反射的函數:函數

def hasattr(*args, **kwargs): # real signature unknown
    """
    Return whether the object has an attribute with the given name.
    
    This is done by calling getattr(obj, name) and catching AttributeError.
    """
    pass

hasattr
def setattr(x, y, v): # real signature unknown; restored from __doc__
    """
    Sets the named attribute on the given object to the specified value.
    
    setattr(x, 'y', v) is equivalent to ``x.y = v''
    """
    pass

setattr
def delattr(x, y): # real signature unknown; restored from __doc__
    """
    Deletes the named attribute from the given object.
    
    delattr(x, 'y') is equivalent to ``del x.y''
    """
    pass

delattr

應用:ui

#!/usr/bin/env python
# -*- coding:utf-8 -*-
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)
#1.檢查是否含有某屬性
print(hasattr(obj,"name")) #有該屬性返回True
print(hasattr(obj,"six"))  #無該屬性返回False
#2.獲取該屬性
n = getattr(obj,"name")
print(n)
func = getattr(obj,"say_hi")
func()
#3.設置屬性
setattr(obj,'sb',True)
setattr(obj,'show_name',lambda self:self.name+'sb')
print(obj.__dict__) #{'name': 'egon', 'age': 73, 'sb': True, 'show_name': <function <lambda> at 0x0020C660>}
print(obj.show_name(obj)) #egonsb
#4.刪除屬性
delattr(obj,'age')
delattr(obj,'show_name')
delattr(obj,'show_name111')#不存在,則報錯
print(obj.__dict__)

類也是一種屬性this

class Foo(object):
    staticField = "old boy"

    def __init__(self):
        self.name = 'wupeiqi'

    def func(self):
        return 'func'

    @staticmethod
    def bar():
        return 'bar'

print(getattr(Foo,"staticField"))
print(getattr(Foo,"func"))
print(getattr(Foo,"bar"))

模塊:設計

import sys
def s1():
    print("s1")
def s2():
    print("s2")
this_module = sys.modules[__name__]

print(hasattr(this_module, 's1')) #True
print(getattr(this_module, 's2')) #<function s2 at 0x02793780>

__str__和,__repr__

改變對象的字符串顯示__str__,__repr__
自定製格式化字符串__format__rest

format_dict={
    'nat':'{obj.name}-{obj.addr}-{obj.type}',#學校名-學校地址-學校類型
    'tna':'{obj.type}:{obj.name}:{obj.addr}',#學校類型:學校名:學校地址
    'tan':'{obj.type}/{obj.addr}/{obj.name}',#學校類型/學校地址/學校名
}
class School:
    def __init__(self,name,addr,type):
        self.name=name
        self.addr=addr
        self.type=type

    def __repr__(self):
        return 'School(%s,%s)' %(self.name,self.addr)
    def __str__(self):
        return '(%s,%s)' %(self.name,self.addr)

    def __format__(self, format_spec):
        # if format_spec
        if not format_spec or format_spec not in format_dict:
            format_spec='nat'
        fmt=format_dict[format_spec]
        return fmt.format(obj=self)

s1=School('oldboy1','北京','私立')
print('from repr: ',repr(s1))
print('from str: ',str(s1))
print(s1)

'''
str函數或者print函數--->obj.__str__()
repr或者交互式解釋器--->obj.__repr__()
若是__str__沒有被定義,那麼就會使用__repr__來代替輸出
注意:這倆方法的返回值必須是字符串,不然拋出異常
'''
print(format(s1,'nat'))
print(format(s1,'tna'))
print(format(s1,'tan'))
print(format(s1,'asfdasdffd'))
打印結果:
from repr:  School(oldboy1,北京)
from str:  (oldboy1,北京)
(oldboy1,北京)
oldboy1-北京-私立
私立:oldboy1:北京
私立/北京/oldboy1
oldboy1-北京-私立

%s和%r的區別code

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 : class B
repr : class B

item

__getitem__\__setitem__\__delitem__
class Foo:
    def __init__(self,name):
        self.name=name

    def __getitem__(self, item):
        print(self.__dict__[item])

    def __setitem__(self, key, value):
        self.__dict__[key]=value
    def __delitem__(self, key):
        print('del obj[key]時,我執行')
        self.__dict__.pop(key)
    def __delattr__(self, item):
        print('del obj.key時,我執行')
        self.__dict__.pop(item)

f1=Foo('sb')
f1['age']=18
f1['age1']=19
del f1.age1
del f1['age']
f1['name']='alex'
print(f1.__dict__)

__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 Singleton:
    def __new__(cls, *args, **kw):
        if not hasattr(cls, '_instance'):
            cls._instance = object.__new__(cls, *args, **kw)
        return cls._instance

one = Singleton()
two = Singleton()

two.a = 3
print(one.a)
# 3
# one和two徹底相同,能夠用id(), ==, is檢測
print(id(one))
# 29097904
print(id(two))
# 29097904
print(one == two)
# True
print(one is two)

單例模式

__call__

對象後面加括號,觸發執行。
注:構造方法的執行是由建立對象觸發的,即:對象 = 類名() ;而對於 call 方法的執行是由對象後加括號觸發的,即:對象() 或者 類()()orm

class Foo:

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

        print('__call__')


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

__len__

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

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

__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))

__eq__

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

    def __eq__(self,obj):
        if  self.a == obj.a and self.b == obj.b:
            return True
a = A()
b = A()
print(a == b)
邏輯題:
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(84):
    p_lst.append(Person('egon',i,'male'))
#
# print(p_lst)
obj = list(set(p_lst))[0]
print(obj.name,obj.age,obj.sex)
相關文章
相關標籤/搜索