日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

python全栈开发基础【第十七篇】面向对象反射和内置方法

發(fā)布時間:2023/11/27 生活经验 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python全栈开发基础【第十七篇】面向对象反射和内置方法 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一、靜態(tài)方法(staticmethod)和類方法(classmethod)

類方法:有個默認參數(shù)cls,并且可以直接用類名去調(diào)用,可以與類屬性交互(也就是可以使用類屬性)

靜態(tài)方法:讓類里的方法直接被類調(diào)用,就像正常調(diào)用函數(shù)一樣

類方法和靜態(tài)方法的相同點:都可以直接被類調(diào)用,不需要實例化

類方法和靜態(tài)方法的不同點:

  類方法必須有一個cls參數(shù)表示這個類,可以使用類屬性

  靜態(tài)方法不需要參數(shù)

綁定方法:分為普通方法和類方法

     普通方法:默認有一個self對象傳進來,并且只能被對象調(diào)用-------綁定到對象

      類方法:默認有一個cls對象傳進來,并且可以被類和對象(不推薦)調(diào)用-----綁定到類

非綁定方法:靜態(tài)方法:沒有設(shè)置默認參數(shù),并且可以被類和對象(不推薦)調(diào)用-----非綁定

?

# staticmethod和classmethod
class Student:f = open('student', encoding='utf-8')def __init__(self):pass@classmethod #類方法 :有個默認參數(shù)cls,并且可以直接使用類名去#調(diào)用,還可以與類屬性交互(也就是可以使用類屬性)def show_student_info_class(cls):# f = open('student', encoding='utf-8')for line in cls.f:name,sex = line.strip().split(',')print(name,sex)@staticmethod  #靜態(tài)方法:可以直接使用類名去調(diào)用,就像正常的函數(shù)調(diào)用一樣def show_student_info_static(): #不用傳selff = open('student',encoding='utf-8')for line in f:name,sex = line.strip().split(',')print(name,sex)
# egon = Student()
# egon.show_student_info_static()  #也可以這樣調(diào),但是還是推薦用類名去調(diào)
# egon.show_student_info_class()Student.show_student_info_class()#類名.方法名()
print('-------------------')
Student.show_student_info_static()#類名.方法名()

isinstance 和 issubclass

isinstance(obj,cls):檢查obj是不是cls的對象(傳兩個參數(shù),一個是對象,一個是類)

issubclass(sub,super):檢查sub是不是super的子類(傳兩個參數(shù),一個是子類,一個是父類)

class Foo:pass
class Son(Foo):pass
s = Son()
print(isinstance(s,Son))  #判斷s是不是Son的對象
print(type(s) is Son)
print(isinstance(s,Foo))  #判斷s是不是Foo的對象  不精準
print(type(s) is Foo)  #type比較精準print(issubclass(Son,Foo)) #判斷Son是不是Foo的子類
print(issubclass(Son,object))
print(issubclass(Foo,object))
print(issubclass(int,object))

  

?

二、反射

反射:可以用字符串的方式去訪問對象的屬性,調(diào)用對象的方法(但是不能去訪問方法),python中一切皆對象,都可以使用反射。

反射有四種方法:

hasattr:hasattr(object,name)判斷一個對象是否有name屬性或者name方法。有就返回True,沒有就返回False

getattr:獲取對象的屬性或者方法,如果存在則打印出來。hasattr和getattr配套使用

    需要注意的是,如果返回的是對象的方法,返回出來的是對象的內(nèi)存地址,如果需要運行這個方法,可以在后面添加一對()

setattr:給對象的屬性賦值,若屬性不存在,先創(chuàng)建后賦值

delattr:刪除該對象指定的一個屬性

# setattr
class Foo:def __init__(self):self.name = 'egon'self.age = 51def func(self):print('hello')
egg = Foo()
setattr(egg,'sex','男')
print(egg.sex)
# 2.
def show_name(self):print(self.name+'sb')
setattr(egg,'sh_name',show_name)
egg.sh_name(egg)
show_name(egg)
delattr(egg,'name')
print(egg.name)

1.對象應(yīng)用反射

# 對象應(yīng)用反射
class Foo:def __init__(self):self.name = 'egon'self.age = 51def func(self):print('hello')
egg = Foo()
print(hasattr(egg,'name'))  #先判斷name在egg里面存在不存在
print(getattr(egg,'name')) #如果為True它才去得到
print(hasattr(egg,'func'))
print(getattr(egg,'func'))  #得到的是地址
# getattr(egg,'func')()  #在這里加括號才能得到,因為func是方法
if hasattr(egg,'func'):getattr(egg,'func')()
else:print('沒找到')

2.類應(yīng)用反射

# 類應(yīng)用反射
class Foo:f = 123@classmethoddef class_method_dome(cls):print('class_method_dome')@staticmethoddef static_method_dome():print('static_method_dome')
print(hasattr(Foo,'class_method_dome'))
method = getattr(Foo,'class_method_dome')
method()
print('------------')
print(hasattr(Foo,'static_method_dome'))
method1 = getattr(Foo,'static_method_dome')
method1()

3.模塊應(yīng)用反射

 模塊的應(yīng)用又分為導入其他模塊反射和在本模塊中反射

# 1.導入其他模塊引用
import mymodule
print(hasattr(mymodule,'test'))
getattr(mymodule,'test')()# # 這里的getattr(mymodule,'test')()這一句相當于
# p = getattr(mymodule,'test')
# p()
# 2.在本模塊中應(yīng)用反射
def demo1():print('wwww')
import sys
# print(sys.modules)
module_obj = sys.modules[__name__]  #相當于'__main__'
print(module_obj)
print(hasattr(module_obj,'demo1'))
getattr(module_obj,'demo1')()
# 舉例
def 注冊():print('regiester')
def 登錄():print('login')
def 購物():pass
print('注冊,登錄,購物')
ret = input('請輸入你要做的操作:')
import sys
my_module = sys.modules[__name__]  #利用sys模塊導入一個自己的模塊
if hasattr(my_module,ret):getattr(my_module,ret)()?

?

三、內(nèi)置方法

1.__str__和__repr__

改變對象的字符串顯示

#  __str__和__repr__
class Foo:def __init__(self,name):self.name = namedef __repr__(self):return 'obj in str'  #這里只能是return# def __str__(self):#     return '%s obj in str'%self.name
f = Foo('egon')
print(f)  #優(yōu)先執(zhí)行__str__里面的內(nèi)容
# 那么你是不是據(jù)地__repr__沒用呢?
# print('%s'%f)  #執(zhí)行的是__str__里面的返回值
# print('%r'%f)  #執(zhí)行的是__repr__里面的返回值
print('==============')
print(str(f))  #當執(zhí)行str(f)時,會去找__str__這個方法,如果找不到的時候,__repr__這個方法就給替補了
print(repr(f))
#1.當打印一個對象的時候,如果實現(xiàn)了__str__方法,打印__str__中的返回值
# 2.當__str__沒有被實現(xiàn)的時候,就會調(diào)用__repr__方法
# 3.但是當你用字符串格式化的時候,%s和%r會分別調(diào)用__str__和__repr__方法
# 4.不管是在字符串格式化的時候還是在打印對象的時候,
# __repr__方法都可以作為__str__方法的替補,但反之則不行
# 5.用于友好的表示對象。如果__str__和__repr__方法你只能實現(xiàn)一個:先實現(xiàn)__repr__

?2.__del__

析構(gòu)方法,當對象在內(nèi)存中被釋放時,自動觸發(fā)執(zhí)行。

注:此方法一般無須定義,因為Python是一門高級語言,程序員在使用時無需關(guān)心內(nèi)存的分配和釋放,因為此工作都是交給Python解釋器來執(zhí)行,所以,析構(gòu)函數(shù)的調(diào)用是由解釋器在進行垃圾回收時自動觸發(fā)執(zhí)行的。

class Foo:def __del__(self):print('執(zhí)行我啦')f= Foo()
print(123)
print(123)
print(123)
print(123)

3.item系列

分別有__getitem__ ? ? ?,__setitem__ ? ?,__delitem__

class Foo:def __init__(self):self.name = 'egon'self.age = 73self.l=[1,2,3]def __getitem__(self, item):  #得到# return  self.l[item]# return self.__dict__[item]# print(Foo.__dict__)return 123def __setitem__(self, key, value):  #修改print(key,value)self.__dict__[key] = valuedef __delitem__(self, key):  #刪除del self.__dict__[key]
f = Foo()
print(f['qqq'])  #不管里面放的啥值,它都會得到返回值的內(nèi)容,調(diào)用的是__getitem__方法
f['name']='alex' #修改egon的值為alex,調(diào)用 __setitem__方法
# del f['name'] #刪除name,就會報錯了,說明在調(diào)用__delitem__方法調(diào)用成功了,就已經(jīng)刪了,就會報錯了
print(f.name) 
f1 = Foo()
print(f == f1)
# print(f.name)
# print(f[0])  #一開始不能這樣取值,但是提供了一個__getitem__方法,這樣就可以用了
# print(f[1])
# print(f[2])

4.__new__(創(chuàng)建)

# 單例模式
# 4.__new__方法
# 單例模式:是一種設(shè)計模式
class Singleton:def __new__(cls, *args, **kw):if not hasattr(cls, '_instance'):orig = super(Singleton, cls)cls._instance = orig.__new__(cls, *args, **kw)return cls._instanceone = Singleton()
two = Singleton()
print(one,two)   #他們兩個的地址一樣one.name = 'alex'
print(two.name) 
#__new__
# class A: # def __init__(self): #有一個方法在幫你創(chuàng)造self # print('in init function') # self.x = 1 # # def __new__(cls, *args, **kwargs): # print('in new function') # return object.__new__(A, *args, **kwargs) # a = A() # b = A() # c = A() # d = A() # print(a,b,c,d)

  

5.__call__

對象后面加括號,觸發(fā)執(zhí)行

注:構(gòu)造方法的執(zhí)行是由創(chuàng)建對象觸發(fā)的,即:對象 = 類名() ;而對于 __call__ 方法的執(zhí)行是由對象后加括號觸發(fā)的,即:對象() 或者 類()()

class Foo:def __call__(self, *args, **kwargs):print(123)
# f = Foo()
# f() #如果不寫上面的__call__方法,就不會調(diào)用。如果加上,就正確了
Foo()() #也可以這樣表示

6.__len__

7.__hash__

class Foo:
def __hash__(self):
print('aaaaaaaaaa')
return hash(self.name)
# print('aaas')
f = Foo()
f.name = 'egon'
print(hash(f)) #hash方法是可以重寫的

8.__eq__

class A:
def __eq__(self, other):
return True
a = A()
b = A()
print(a==b) #不加方法的時候返回的是False,加了個__eq__方法就返回了個True
# '=='內(nèi)部就調(diào)用了__eq__方法
print(a is b)

?

一道面試題

?

# 紙牌游戲
from collections import namedtuple
Card = namedtuple('Card',['rank','suit'])  #兩個屬性:一個是數(shù),一個是花色(每一個card的對象就是一張紙牌)
class FranchDeck: #紙牌數(shù)據(jù)類型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 #先循環(huán)這個,在循環(huán)下面的那個循環(huán)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] = valuedeck = FranchDeck()
# print(deck[0])
# print(deck[0])
# print(deck[0])
# print(deck[0])
from random import choice
print(choice(deck))
print(choice(deck))from random import shuffle
shuffle(deck)
print(deck[:5])

  

?

轉(zhuǎn)載于:https://www.cnblogs.com/xiaohema/p/8453850.html

總結(jié)

以上是生活随笔為你收集整理的python全栈开发基础【第十七篇】面向对象反射和内置方法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。