詳解自動化運維Python系列之面向對象

高洛峰
發布: 2017-03-26 18:53:33
原創
1744 人瀏覽過

物件導向程式設計

導向流程:根據業務邏輯從上到下壘程式碼

函數式:將某功能程式碼封裝到函數中,以後直接調用,不需要再次編寫

物件導向:對函數進行分類和封裝,讓開發「更快更好更強...」

# 像Java和C#等程式語言僅支援物件導向編程,而Python支援函數式程式設計和物件導向程式設計混用

物件導向範例

# 函数式编程 def bar(): print('bar') bar() # 直接调用函数 # 面向对象编程 class Foo: # 创建类 def bar(self): # 在类里面定义函数 这里self是一个特殊的参数 创建对象时Foo将自身传进来 print('bar') obj = Foo() # 创建一个对象 obj.bar() # 由对象去访问类里面函数
登入後複製

物件導向的三大特性:封裝繼承多型別

封裝

將我們需要的內容封裝進創建的類,需要的時候再去調用

class Foo: # 创建类 def __init__(self, name, age): # Foo接收到两个参数后会封装在自己类内部 self.name = name self.age = age obj = Foo('kobe', 18) # 创建一个对象 传两个参数 print(obj.name, obj.age) # 外面调用封装好的参数 输出: kobe 18
登入後複製

類成員

字段:普通字段、靜態字段

方法:普通方法、靜態方法、類別方法

屬性:普通屬性

1)欄位(類別裡面封裝的參數)

class Foo: # 字段(静态字段 保存在类里面) CC = "中国" def __init__(self, name): # 字段(普通的字段 保存在对象里面) self.name = name # 普通字段通过对象访问 obj = Foo('上海') print(obj.name) # 静态字段通过类访问 print(Foo.CC)
登入後複製

2)方法(類別裡面封裝的函數)

class Foo: def show(self): # 普通方法:对象调用执行 方法属于类 print(self.name) @staticmethod def f1(): # 静态方法 由类调用执行 print('f1') @classmethod def f2(cls): # class 自动给类名传进去了 # 类方法 # cls 是类名 加()创建对象 print(cls) # 创建对象 obj = Foo() # 通过对象去访问普通方法 obj.show() # 通过类去访问静态方法 Foo.f1() # 类方法 会将类 Foo 名字直接传入函数 Foo.f2()
登入後複製

3)屬性

在沒有定義類別的屬性之前,我們存取類別中的方法需要在方法名稱後面加括號():例如obj. f1()

定義屬性之後,我們存取類別中的方法可以直接obj.f1

class Foo: @property def f1(self): print('f1') obj = Foo() obj.f1 # 无需加括号直接通过对象访问
登入後複製

可設定、可刪除

class Foo: @property # 在类方法上加上 property装饰器 def f1(self): print('f1') @f1.setter # 设置数值 def f1(self, values): print(values) @f1.deleter # 可删除 def f1(self): print('del...') obj = Foo() obj.f1 # 无需加括号直接通过对象访问 obj.f2 = 100 del obj.f1 输出: f1 del...
登入後複製

類別屬性的另一種寫入方法

class Foo: def f1(self): return 100 def f2(self, value): print(value) def f3(self): print('300') # 类属性定义 Foo = property(fget=f1, fset=f2, fdel=f3) obj = Foo() # 取值 ret = obj.Foo print(ret) # 赋值 obj.Foo = 200 # 删除 del obj.Foo # 输出 100 200 300
登入後複製

類別成員修飾符

類別成員修飾符:將類別中的欄位或方法定義為公有或私有

公有成員:在任何地方都可以存取

私有成員:只有在類別內部才能被存取

class Foo: __cc = 123 def __init__(self, name): self.__name = name # 加两个下划线__表示私有字段 外部、继承都不能调用 def f1(self): print(self.__name) @staticmethod # 加 staticmethod 装饰器表示为静态方法,可以不加self参数直接外部调用 def f3(self): print(Foo.__cc) obj = Foo('kobe') # print(obj.__name) # 通过对象外部访问内部普通字段不成功 obj.f1() # print(Foo.__cc) # 通过外部访问内部静态字段也不成功 obj.f3() # 特殊访问方法 print(obj._Foo__name)
登入後複製

類別的特殊成員

__doc__ # 類別的描述資訊

__module__ # 當前物件在哪個模組

__class__ # 目前物件屬於哪個類別

__str__ # 列印物件時傳回的值

__in#__ 建構方法
__del__ # 析構方法

__call__ # 物件後面加上括號觸發執行

__dict__ # 類別或物件中的所有成員

# __getitem__# 運算# #1__

##__setitem__ # 索引操作

__delitem__ # 索引作業

1)__doc__ 描述訊息

class Foo: """ 注释 __doc__ """ obj = Foo() print(obj.__doc__) 输出: 注释 __doc__ 2)__module__ 和 __class__ from lib.aa import C obj = C() print obj.__module__ # 输出 lib.aa,即:输出模块 print obj.__class__ # 输出 lib.aa.C,即:输出类
登入後複製

3)__init__ 與__str__

rree

4)__del__

class Foo: def __init__(self, name, age): # 构造方法 self.name = name self.age = age def __str__(self): # str方法 return '%s - %s ' % (self.name, self.age) obj1 = Foo(name='kobe', age=18) obj2 = Foo(name='jordan', age=18) print(obj1) print(obj2) # 输出: kobe - 18 jordan - 18
登入後複製

5)__call__

class Foo: def __init__(self, name, age): # 构造方法 self.name = name self.age = age # 析构方法:在垃圾回收之前执行 def __del__(self): pass
登入後複製

6)__dict__

class Foo: def __call__(self, *args, **kwargs): print('call') p = Foo() # 对象后面加括号执行 __call__ 方法 p() # 一个括号是类创建了一个对象 两个括号是去执行 __call__ 方法 Foo()() # 输出: call call
登入後複製

6)__getitem__ __setitem__ delitem__ 用於索引運算、如字典:可以#6)__getitem__ __setitem__ delitem__ 用於索引運算、如字典可以:可以#6)__getitem__取得值、設定、刪除

class Foo: def __init__(self, name, age): # 构造方法 self.name = name self.age = age obj1 = Foo(name='kobe', age=18) # 获取对象中封装的数据返回一个字典 ret = obj1.__dict__ print(ret) # 输出: {'name': 'kobe', 'age': 18} # 全部的类方法 # print(Foo.__dict__)
登入後複製

7)__iter__、 __isinstance__、__issubclass__

class Foo: def __getitem__(self, item): print('getitem') def __setitem__(self, key, value): print('setitem') print(item.start, item.stop, item.step) def __delitem__(self, key): print('delitem') # 中括号语法自动执行 getitem 方法 obj = Foo() obj['ab'] # 中括号并且赋值执行 setitem 方法 obj['k1'] = 111 del obj['k1'] # 切片也是去执行 setitem 方法 obj[1:6:2] # 输出 setitem delitem getitem 1 6 2
登入後複製

super

#super 是為了解決Python中的多重繼承問題,強行去執行父類別中的方法

class Bar: pass class Foo(Bar): # 返回一个可迭代对象 def __iter__(self): # return iter([11, 22, 33, 44]) yield 1 yield 2 obj = Foo() for item in obj: print(item) # 查看 obj 是否是 Foo 的实例 ret = isinstance(obj, Foo) # 也可以查看是否是 父类 的实例 # ret = isinstance(obj, Bar) print(ret) # 查看 Foo 是否为 Bar 的子类 ret1 = issubclass(Foo, Bar) print(ret1) # 输出 1 2 True True
登入後複製

利用super在不改變原始碼情況添加功能的方法

class C1: def f1(self): print('c1.f1') class C2(C1): def f1(self): # 主动执行父类的 f1 方法 super(C2, self).f1() print('c2.f1') obj = C2() obj.f1() # 输出: c1.f1 c2.f1
登入後複製

利用super實作有序字典

目录 backend - commons.py index.py lib.py setting.py commons.py >> class Foo: def f1(self): print('Foo.f1') index.py >> from setting import ClassName from setting import Path def execute(): model = __import__(Path, fromlist=True) cls = getattr(model, ClassName) obj = cls() obj.f1() if __name__ == '__main__': execute() setting >> # Path = "backend.commons" # ClassName = 'Foo' Path = "lib" ClassName = 'MyFoo' lib >> from backend.commons import Foo class MyFoo(Foo): def f1(self): print('before') super(MyFoo, self).f1() print('after') 这样运行我们自己添加的lib 时结果如下 before Foo.f1 after
登入後複製

單例模式

## 單例模式是常用的軟體設計模式。在它的核心結構中只包含一個被稱為單例類別的特殊類別。透過單例模式可以確保系統中一個類別只有一個實例而且該實例易於外界訪問,從而方便對實例個數的控制並節約系統資源。如果希望在系統中某個類別的物件只能存在一個,單例模式是最好的解決方案。

class MyDict(dict): def __init__(self): self.li = [] super(MyDict, self).__init__() def __setitem__(self, key, value): self.li.append(key) super(MyDict, self).__setitem__(key, value) def __str__(self): temp_list = [] for key in self.li: value = self.get(key) temp_list.append("'%s':%s" % (key, value)) temp_str = "{" + ",".join(temp_list) + "}" return temp_str obj = MyDict() obj['k1'] = 123 obj['k2'] = 456 print(obj) # 输出 {'k1':123,'k2':456}
登入後複製

異常處理

class Foo: instance = None def __init__(self, name): self.name = name @classmethod def get_instance(cls): if cls.instance: return cls.instance else: obj = cls('alex') cls.instance = obj return obj obj1 = Foo.get_instance() obj2 = Foo.get_instance() print(obj1) print(obj2) # 输出 <__main__.Foo object at 0x000001C09B130B70> <__main__.Foo object at 0x000001C09B130B70>
登入後複製

異常處理完整程式碼

while True: num1 = input('num1: ') num2 = input('num2: ') try: num1 = int(num1) num2 = int(num2) ret = num1 + num2 except Exception as ex: print(ex) except ValueError as ex: print(ex) except IndexError as ex: print(ex)
登入後複製

以上是詳解自動化運維Python系列之面向對象的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!