1. 程式人生 > >python中的幾個高階問題詳解(__init__,裝飾器執行步驟,@staticmethod和@classmethod區別,單例模式,魔法方法,object繼承與不繼承區別)

python中的幾個高階問題詳解(__init__,裝飾器執行步驟,@staticmethod和@classmethod區別,單例模式,魔法方法,object繼承與不繼承區別)

第一個問題,init
在定義一個類時,什麼時候用__init__函式,什麼時候不用,用不用有什麼區別?

首先__init__是為了初始化用的,但是初始化的時候不一定要用這個,直接定義也是可以的,比如

class A(object):
	test_a = '123'

而我們用__init__的好處在於可以接受任何引數並初始化

def __init__(self,a):
	test_a = a

這樣類可以初始化一個動態的變數,更加靈活,直接test(‘123’)就將test_a初始化成123了
再舉一個例子,如下

# 不用init方法定義類
class Rectangle(object):
    def getPeri(self,a,b):
        return (a+b)*2
    def getArea(self,a,b):
        return a*b
rec = Rectangle()
print(rec.getPeri(3,4))  # 14 
print(rec.getArea(3,4))  # 12
print(rec.__dict__)  # {}

從上例可以看到,沒有定義__init__方法,也能得到周長和麵積,但是通過rec.__dict__來看這個例項的屬性,是空的,這就是沒有定義__init__的原因。
並且,在例項化物件時,rec=Rectangle()引數為空,沒有指定a,b的值,只有在呼叫函式的時候才指定,且類中定義的每個方法的引數都有a,b,有點多餘了。
因此,需要在類中定義__init__方法,方便建立例項的時候,需要給例項繫結上屬性,也方便類中的方法定義。
上述同樣的例子,用__init__方法定義類,如下

# 使用__init__方法定義類
class Rectangle(object):
    def __init__(self,a,b):
        self.a = a
        self.b = b
    def getPeri(self):
        return (self.a+self.b)*2
    def getArea(self):
        return self.a*self.b

rec = Rectangle(3,4)
print(rec.getPeri())  # 14
print(rec.getArea())  # 12
print(rec.__dict__)  # {'a': 3, 'b': 4}

定義完init()方法後,建立的每個例項都有自己的屬性,也方便直接呼叫類中的函式。