摘要:它首先被程序語言的設計領域所采用并在和面向對象方面取得了成績。面向對象中的反射通過字符串的形式操作對象相關的屬性。注構造方法的執行是由創建對象觸發的,即對象類名而對于方法的執行是由對象后加括號觸發的,即對象或者類執行執行邏輯題
isinstance和issubclass
1.isinstance(obj,cls)檢查是否obj是否是類 cls 的對象
#!/usr/bin/env python # -*- coding:utf-8 -*- class Foo: pass obj = Foo() print(isinstance(obj,Foo))
2.issubclass(cls,cls)檢查Bar是否是Foo的派生類
#!/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
應用:
#!/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":at 0x0020C660>} print(obj.show_name(obj)) #egonsb #4.刪除屬性 delattr(obj,"age") delattr(obj,"show_name") delattr(obj,"show_name111")#不存在,則報錯 print(obj.__dict__)
類也是一種屬性
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")) #__str__和,__repr__
改變對象的字符串顯示__str__,__repr__
自定制格式化字符串__format__
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的區別
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 Bitem
__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 方法的執行是由對象后加括號觸發的,即:對象() 或者 類()()
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)
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/41983.html
摘要:如果初學者接觸的第一門語言是,學習曲線則會平滑得多,掌握一些基本語法和內置的數據結構,已經可以上手寫一些小工具或者小型應用。如果你的學習時間充足,我的建議是一定要學數據結構和算法。 前言 Python是最容易入門的編程語言,沒有之一。如果初學者接觸的第一門語言是C或者C++,對他們來說最難的不是語法,而是容易出現內存泄漏、指針等問題。有時候排查這些問題對初學者的打擊很大,尤其是沒掌握排...
摘要:本文是切片系列的第三篇,主要內容是迭代器切片。實際上,迭代器必然是可迭代對象,但可迭代對象不一定是迭代器。這是迭代器切片最具想象力的用途場景。考慮到文件對象天然就是迭代器,我們可以使用迭代器切片先行截取,然后再處理,如此效率將大大地提升。 2018-12-31 更新聲明:切片系列文章本是分三篇寫成,現已合并成一篇。合并后,修正了一些嚴重的錯誤(如自定義序列切片的部分),還對行文結構與章...
摘要:本文是切片系列的第三篇,主要內容是迭代器切片。實際上,迭代器必然是可迭代對象,但可迭代對象不一定是迭代器。這是迭代器切片最具想象力的用途場景。考慮到文件對象天然就是迭代器,我們可以使用迭代器切片先行截取,然后再處理,如此效率將大大地提升。 2018-12-31 更新聲明:切片系列文章本是分三篇寫成,現已合并成一篇。合并后,修正了一些嚴重的錯誤(如自定義序列切片的部分),還對行文結構與章...
閱讀 3110·2021-11-24 09:39
閱讀 968·2021-09-07 10:20
閱讀 2389·2021-08-23 09:45
閱讀 2254·2021-08-05 10:00
閱讀 566·2019-08-29 16:36
閱讀 833·2019-08-29 11:12
閱讀 2813·2019-08-26 11:34
閱讀 1839·2019-08-26 10:56