python面向對象之反射和內置方法

1、靜態方法(staticmethod)和類方法(classmethod)python

類方法:有個默認參數cls,而且能夠直接用類名去調用,能夠與類屬性交互(也就是可使用類屬性)mysql

靜態方法:讓類裏的方法直接被類調用,就像正常調用函數同樣程序員

類方法和靜態方法的相同點:均可以直接被類調用,不須要實例化sql

類方法和靜態方法的不一樣點:設計模式

  類方法必須有一個cls參數表示這個類,可使用類屬性dom

  靜態方法不須要參數函數

綁定方法:分爲普通方法和類方法fetch

     普通方法:默認有一個self對象傳進來,而且只能被對象調用-------綁定到對象spa

      類方法:默認有一個cls對象傳進來,而且能夠被類和對象(不推薦)調用-----綁定到類設計

非綁定方法:靜態方法:沒有設置默認參數,而且能夠被類和對象(不推薦)調用-----非綁定

class Student:
 2     f = open('student', encoding='utf-8')
 3     def __init__(self):
 4         pass
 5     @classmethod #類方法 :有個默認參數cls,而且能夠直接使用類名去
 6                  #調用,還能夠與類屬性交互(也就是可使用類屬性)
 7     def show_student_info_class(cls):
 8         # f = open('student', encoding='utf-8')
 9         for line in cls.f:
10             name,sex = line.strip().split(',')
11             print(name,sex)
12     @staticmethod  #靜態方法:能夠直接使用類名去調用,就像正常的函數調用同樣
13     def show_student_info_static(): #不用傳self
14         f = open('student',encoding='utf-8')
15         for line in f:
16             name,sex = line.strip().split(',')
17             print(name,sex)
18 # egon = Student()
19 # egon.show_student_info_static()  #也能夠這樣調,可是仍是推薦用類名去調
20 # egon.show_student_info_class()
21 
22 Student.show_student_info_class()#類名.方法名()
23 print('-------------------')
24 Student.show_student_info_static()#類名.方法名()

1、isinstance 和 issubclass

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

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

複製代碼
 1 class Foo:
 2     pass
 3 class Son(Foo):
 4     pass
 5 s = Son()
 6 print(isinstance(s,Son))  #判斷s是否是Son的對象
 7 print(type(s) is Son)
 8 print(isinstance(s,Foo))  #判斷s是否是Foo的對象  不精準
 9 print(type(s) is Foo)  #type比較精準
10 
11 print(issubclass(Son,Foo)) #判斷Son是否是Foo的子類
12 print(issubclass(Son,object))
13 print(issubclass(Foo,object))
14 print(issubclass(int,object))
複製代碼

2、反射

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

反射有四種方法:

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

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

    須要注意的是,若是返回的是對象的方法,返回出來的是對象的內存地址,若是須要運行這個方法,能夠在後面添加一對()

setattr:給對象的屬性賦值,若屬性不存在,先建立後賦值

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

class Foo:
 2     def __init__(self):
 3         self.name = 'egon'
 4         self.age = 51
 5     def func(self):
 6         print('hello')
 7 egg = Foo()
 8 setattr(egg,'sex','男')
 9 print(egg.sex)
10 # 2.
11 def show_name(self):
12     print(self.name+'sb')
13 setattr(egg,'sh_name',show_name)
14 egg.sh_name(egg)
15 show_name(egg)

 

delattr(egg,'name')
2 print(egg.name)

1.對象應用反射
class Foo:
 2     def __init__(self):
 3         self.name = 'egon'
 4         self.age = 51
 5     def func(self):
 6         print('hello')
 7 egg = Foo()
 8 print(hasattr(egg,'name'))  #先判斷name在egg裏面存在不存在
 9 print(getattr(egg,'name')) #若是爲True它纔去獲得
10 print(hasattr(egg,'func'))
11 print(getattr(egg,'func'))  #獲得的是地址
12 # getattr(egg,'func')()  #在這裏加括號才能獲得,由於func是方法
13 if hasattr(egg,'func'):
14     getattr(egg,'func')()
15 else:
16     print('沒找到')

2.類應用反射
class Foo:
 2     f = 123
 3     @classmethod
 4     def class_method_dome(cls):
 5         print('class_method_dome')
 6 
 7     @staticmethod
 8     def static_method_dome():
 9         print('static_method_dome')
10 print(hasattr(Foo,'class_method_dome'))
11 method = getattr(Foo,'class_method_dome')
12 method()
13 print('------------')
14 print(hasattr(Foo,'static_method_dome'))
15 method1 = getattr(Foo,'static_method_dome')
16 method1()

3.模塊應用反射

 模塊的應用又分爲導入其餘模塊反射和在本模塊中反射

# 1.導入其餘模塊引用
2 import mymodule
3 print(hasattr(mymodule,'test'))
4 getattr(mymodule,'test')()
5 
6 # # 這裏的getattr(mymodule,'test')()這一句至關於
7 # p = getattr(mymodule,'test')
8 # p()

# 2.在本模塊中應用反射
2 def demo1():
3     print('wwww')
4 import sys
5 # print(sys.modules)
6 module_obj = sys.modules[__name__]  #至關於'__main__'
7 print(module_obj)
8 print(hasattr(module_obj,'demo1'))
9 getattr(module_obj,'demo1')()

# 舉例
 2 def 註冊():
 3     print('regiester')
 4 def 登陸():
 5     print('login')
 6 def 購物():
 7     pass
 8 print('註冊,登陸,購物')
 9 ret = input('請輸入你要作的操做:')
10 import sys
11 my_module = sys.modules[__name__]  #利用sys模塊導入一個本身的模塊
12 if hasattr(my_module,ret):
13     getattr(my_module,ret)()

反射補充:

db.mysql

class MySQlHelper(object):
    print('MySQlHelper1111111')
    def fetchone(self):
        print('你好')

db.pool

class PoolHelper(object):
    print('PoolHelper')

settings.py

複製代碼
DB_PATH = 'db.mysql.MySQlHelper'

#吧字符串切割
module_name,cls_name = DB_PATH.rsplit('.',maxsplit=1)
# print(module_name,cls_name)  #db.mysql    MySQlHelper
#導入模塊
# from db.mysql import MySQlHelper
import importlib
moudel_obj = importlib.import_module(module_name)
print(moudel_obj,type(moudel_obj))
#導入模塊中的類
cls = getattr(moudel_obj,cls_name)
print(cls)
#對類進行實例化
obj = cls()
obj.fetchone()
# getattr()
複製代碼

3、內置方法

1.__str__和__repr__

改變對象的字符串顯示

class Foo:
 2     def __init__(self,name):
 3         self.name = name
 4     def __repr__(self):
 5         return 'obj in str'  #這裏只能是return
 6     # def __str__(self):
 7     #     return '%s obj in str'%self.name
 8 f = Foo('egon')
 9 print(f)  #優先執行__str__裏面的內容
10 # 那麼你是否是據地__repr__沒用呢?
11 # print('%s'%f)  #執行的是__str__裏面的返回值
12 # print('%r'%f)  #執行的是__repr__裏面的返回值
13 print('==============')
14 print(str(f))  #當執行str(f)時,會去找__str__這個方法,若是找不到的時候,__repr__這個方法就給替補了
15 print(repr(f))
16 #1.當打印一個對象的時候,若是實現了__str__方法,打印__str__中的返回值
17 # 2.當__str__沒有被實現的時候,就會調用__repr__方法
18 # 3.可是當你用字符串格式化的時候,%s和%r會分別調用__str__和__repr__方法
19 # 4.無論是在字符串格式化的時候仍是在打印對象的時候,
20 # __repr__方法均可以做爲__str__方法的替補,但反之則不行
21 # 5.用於友好的表示對象。若是__str__和__repr__方法你只能實現一個:先實現__repr__

 

2.__del__

析構方法,當對象在內存中被釋放時,自動觸發執行。

注:此方法通常無須定義,由於Python是一門高級語言,程序員在使用時無需關心內存的分配和釋放,由於此工做都是交給Python解釋器來執行,因此,析構函數的調用是由解釋器在進行垃圾回收時自動觸發執行的。

複製代碼
1 class Foo:
2     def __del__(self):
3         print('執行我啦')
4 
5 f= Foo()
6 print(123)
7 print(123)
8 print(123)
9 print(123)
複製代碼

3.item系列

分別有__getitem__      ,__setitem__    ,__delitem__

class Foo:
 2     def __init__(self):
 3         self.name = 'egon'
 4         self.age = 73
 5         self.l=[1,2,3]
 6     def __getitem__(self, item):  #獲得
 7         # return  self.l[item]
 8         # return self.__dict__[item]
 9         # print(Foo.__dict__)
10         return 123
11     def __setitem__(self, key, value):  #修改
12         print(key,value)
13         self.__dict__[key] = value
14     def __delitem__(self, key):  #刪除
15         del self.__dict__[key]
16 f = Foo()
17 print(f['qqq'])  #無論裏面放的啥值,它都會獲得返回值的內容,調用的是__getitem__方法
18 f['name']='alex' #修改egon的值爲alex,調用 __setitem__方法
19 # del f['name'] #刪除name,就會報錯了,說明在調用__delitem__方法調用成功了,就已經刪了,就會報錯了
20 print(f.name) 
21 f1 = Foo()
22 print(f == f1)
23 # print(f.name)
24 # print(f[0])  #一開始不能這樣取值,可是提供了一個__getitem__方法,這樣就能夠用了
25 # print(f[1])
26 # print(f[2])

4.__new__(建立)
# 4.__new__方法
 2 # 單例模式:是一種設計模式
 3 class Singleton:
 4     def __new__(cls, *args, **kw):
 5         if not hasattr(cls, '_instance'):
 6             orig = super(Singleton, cls)
 7             cls._instance = orig.__new__(cls, *args, **kw)
 8         return cls._instance
 9 
10 one = Singleton()
11 two = Singleton()
12 print(one,two)   #他們兩個的地址同樣
13 
14 one.name = 'alex'
15 print(two.name) 

 

# class A:
 2 #     def __init__(self):  #有一個方法在幫你創造self
 3 #         print('in init function')
 4 #         self.x = 1
 5 #
 6 #     def __new__(cls, *args, **kwargs):
 7 #         print('in new function')
 8 #         return object.__new__(A, *args, **kwargs)
 9 # a = A()
10 # b = A()
11 # c = A()
12 # d = A()
13 # print(a,b,c,d)

5.__call__

對象後面加括號,觸發執行

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

class Foo:
2     def __call__(self, *args, **kwargs):
3         print(123)
4 # f = Foo()
5 # f() #若是不寫上面的__call__方法,就不會調用。若是加上,就正確了
6 Foo()() #也能夠這樣表示

6.__len__

7.__hash__
class Foo:
2     def __hash__(self):
3         print('aaaaaaaaaa')
4         return hash(self.name)
5         # print('aaas')
6 f = Foo()
7 f.name = 'egon'
8 print(hash(f))  #hash方法是能夠重寫的

 8.__eq__

class A:
2     def __eq__(self, other):
3         return True
4 a = A()
5 b = A()
6 print(a==b) #不加方法的時候返回的是False,加了個__eq__方法就返回了個True
7 # '=='內部就調用了__eq__方法
8 print(a is b)
相關文章
相關標籤/搜索