來自一名java開發人員的python學習(面向對象&常見函數)

黑魔法

python關於屬性的處理可以堪稱黑魔法,不過如果把python的對象看做字典的話也就好理解了,這個時候沒有體現OO中封裝的特性

emp1.age = 7  # 添加一個 'age' 屬性
emp1.age = 8  # 修改 'age' 屬性
del emp1.age  # 刪除 'age' 屬性

你也可以使用以下函數的方式來訪問屬性:

  • getattr(obj, name[, default]) : 訪問對象的屬性。
  • hasattr(obj,name) : 檢查是否存在一個屬性。
  • setattr(obj,name,value) : 設置一個屬性。如果屬性不存在,會創建一個新屬性。
  • delattr(obj, name) : 刪除屬性
    示例如下
hasattr(emp1, 'age')    # 如果存在 'age' 屬性返回 True。
getattr(emp1, 'age')    # 返回 'age' 屬性的值
setattr(emp1, 'age', 8) # 添加屬性 'age' 值爲 8
delattr(emp1, 'age')    # 刪除屬性 'age

繼續按照字典的思路,python提供瞭如下內置屬性

  • dict : 類的屬性(包含一個字典,由類的數據屬性組成)
  • doc :類的文檔字符串
  • name: 類名
  • module: 類定義所在的模塊(類的全名是’main.className’,如果類位於一個導入模塊mymod中,那麼className.module 等於 mymod)
  • bases : 類的所有父類構成元素(包含了一個由所有父類組成的元組

析構函數

析構函數 del ,__del__在對象銷燬的時候被調用,當對象不再被使用時,__del__方法運行

繼承

python中子類繼承父類時子類的構造函數不必調用父類的構造函數


#!/usr/bin/python
# -*- coding: UTF-8 -*-
 
class Parent:        # 定義父類
   parentAttr = 100
   def __init__(self):
      print "調用父類構造函數"
 
   def parentMethod(self):
      print '調用父類方法'
 
   def setAttr(self, attr):
      Parent.parentAttr = attr
 
   def getAttr(self):
      print "父類屬性 :", Parent.parentAttr
 
class Child(Parent): # 定義子類
   def __init__(self):
      print "調用子類構造方法"
 
   def childMethod(self):
      print '調用子類方法'
 
c = Child()          # 實例化子類
c.childMethod()      # 調用子類的方法
c.parentMethod()     # 調用父類方法
c.setAttr(200)       # 再次調用父類的方法 - 設置屬性值
c.getAttr()          # 再次調用父類的方法 - 獲取屬性值

這裏也不存在隱式的調用,所以打印結果如下

調用子類構造方法
調用子類方法
調用父類方法
父類屬性 : 200

super()

子類像調用父類方法使用super()來獲得和java中super3一樣的效果,示例如下

class A:
     def add(self, x):
         y = x+1
         print(y)
class B(A):
    def add(self, x):
        super().add(x)
b = B()
b.add(2)  # 3

操作符重載


#!/usr/bin/python
 
class Vector:
   def __init__(self, a, b):
      self.a = a
      self.b = b
 
   def __str__(self):
      return 'Vector (%d, %d)' % (self.a, self.b)
   
   def __add__(self,other):
      return Vector(self.a + other.a, self.b + other.b)
 
v1 = Vector(2,10)
v2 = Vector(5,-2)
print v1 + v2

方法與屬性

私有屬性

兩個下劃線開頭,聲明該屬性爲私有,不能在類的外部被使用或直接訪問。在類內部的方法中使用時 self.__private_attrs。

黑魔法

Python不允許實例化的類訪問私有數據,但你可以使用 object._className__attrName( 對象名._類名__私有屬性名 )訪問屬性,示例如下

#!/usr/bin/python
# -*- coding: UTF-8 -*-

class Foo:
    __attr = "foo"

foo= Foo()
print foo._Foo__attr

普通方法

在類的內部,使用 def 關鍵字可以爲類定義一個方法,與一般函數定義不同,類方法必須包含參數 self,且爲第一個參數

私有方法

兩個下劃線開頭,聲明該方法爲私有方法,不能在類的外部調用。在類的內部調用 self.__private_methods

@staticmethod

格式如下

class C(object):
    @staticmethod
    def f(arg1, arg2, ...):

@classmethod

與@staticmethod不同的是,classmethod需要第一個參數是自身類的cls參數,對其調用相當於調用了初始化成一個對象,示例如下


#!/usr/bin/python
# -*- coding: UTF-8 -*-
 
class A(object):
    bar = 1
    def func1(self):  
        print ('foo') 
    @classmethod
    def func2(cls):
        print ('func2')
        print (cls.bar)
        cls().func1()   # 調用 foo 方法
 
A.func2()               # 不需要實例化

內置函數

divmod()

這個函數比較好,一次性把商和餘數都求出來了,想想看他倆也經常一起使用,並且更厲害的是支持複數


>>>divmod(7, 2)
(3, 1)
>>> divmod(8, 2)
(4, 0)
>>> divmod(1+2j,1+0.5j)
((1+0j), 1.5j)

eval() & exec() & execfile() & compile()

eval & exec

eval把字符串當做代碼執行,這對於解釋性語言而言不是問題


>>>x = 7
>>> eval( '3 * x' )
21
>>> eval('pow(2,2)')
4
>>> eval('2 + 2')
4
>>> n=81
>>> eval("n + 4")
85

execfile

類似的執行文件可以使用execfile

execfile('hello.py')

compile

而compile是將字符串編譯成函數,可以後續調用,示例如下


>>>str = "for i in range(0,10): print(i)" 
>>> c = compile(str,'','exec')   # 編譯爲字節代碼對象 
>>> c
<code object <module> at 0x10141e0b0, file "", line 1>
>>> exec(c)
0
1
2
3
4
5
6
7
8
9
>>> str = "3 * 4 + 5"
>>> a = compile(str,'','eval')
>>> eval(a)
17

frozenset()

可以從一個可迭代對象生成一個凍結的集合,不能添加和刪除元素,示例如下


>>>a = frozenset(range(10))     # 生成一個新的不可變集合
>>> a
frozenset([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> b = frozenset('runoob') 
>>> b
frozenset(['b', 'r', 'u', 'o', 'n'])   # 創建不可變集合
>>>

vars()

把對象徹底的變成了字典,示例如下


>>>print(vars())
{'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__doc__': None, '__package__': None}
>>> class Runoob:
...     a = 1
... 
>>> print(vars(Runoob))
{'a': 1, '__module__': '__main__', '__doc__': None}
>>> runoob = Runoob()
>>> print(vars(runoob))
{}

globals()

globals() 函數會以字典類型返回當前位置的全部全局變量。

import()

import() 函數用於動態加載類和函數 。

如果一個模塊經常變化就可以使用 import() 來動態載入。

help()

查看模塊的幫助信息


>>>help('sys')             # 查看 sys 模塊的幫助
……顯示幫助信息……
 
>>>help('str')             # 查看 str 數據類型的幫助
……顯示幫助信息……
 
>>>a = [1,2,3]
>>>help(a)                 # 查看列表 list 幫助信息
……顯示幫助信息……
 
>>>help(a.append)          # 顯示list的append方法的幫助
……顯示幫助信息……

dir()

dir() 函數不帶參數時,返回當前範圍內的變量、方法和定義的類型列表;帶參數時,返回參數的屬性、方法列表。如果參數包含方法__dir__(),該方法將被調用。如果參數不包含__dir__(),該方法將最大限度地收集參數信息。

id()

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章