week6:面向物件基礎
一、基本概念
1.1、python 函式式+面向物件
函數語言程式設計可以做所有的事,是否合適?
函式:def+函式名(引數):
二、面向物件
2.1、如何建立類
class 類名:
pass
2.3、建立方法
def __init__(self,arg):
obj = 類('a1')
obj = 類(‘xxx’)
obj.普通方法名()
"""
class Bar:
def foo(self):
print(self.name)
z = Bar()
z.foo()
"""
#self: 代指呼叫方法的物件(中間人)
class Bar: def foo(self, arg): print(self, arg) z1 = Bar() print(z1) z1.foo(111) print('================') z2 = Bar() print(z2) z2.foo(666)
輸出結果:
<__main__.Bar object at 0x00000201C2CC7748>
<__main__.Bar object at 0x00000201C2CC7748> 111
================
<__main__.Bar object at 0x00000201C2CC7CC0>
<__main__.Bar object at 0x00000201C2CC7CC0> 666
class Bar: def foo(self, arg): print(self, self.name, self.age, self.gender, arg) z = Bar() z.name = 'alex' z.age = 84 z.gender = 'zhong' z.foo(666) z1 = Bar() z1.name = 'eric' z1.age = 73 z1.gender = 'nv' z1.foo(666)
輸出結果:
<__main__.Bar object at 0x0000028B41307CC0> alex 84 zhong 666
<__main__.Bar object at 0x0000028B41307D30> eric 73 nv 666
2.4、面向物件三大特性之一:封裝
class Bar:
def __init__(self, n,a):
self.name = n
self.age = a
self.xue = 'o'
b1 = Bar('alex', 123)
b2 = Bar('eric', 456)
class Bar:
def __init__(self,n1,n2,n3):
self.nam1=n1
self.nam2=n2
self.nam3=n3
self.nam4=n3
self.nam5=n3
self.nam6=n3
def foo(self):
print(self.nam1,self.nam2,self.nam3,self.nam4,self.nam5,self.nam6)
z = Bar(1,2,3)
print(z.nam1)
z.foo()
輸出結果:
1
1 2 3 3 3 3
class Person:
def __init__(self, name,age):
#構造方法,構造方法的特性, 類名() 自動執行構造方法
self.n = name
self.a = age
self.x = '0'
def show(self):
print('%s-%s' %(self.n, self.a))
lihuan = Person('李歡', 18)
lihuan.show()
hu = Person('互相林', 73)
hu.show()
輸出結果:
李歡-18
互相林-73
2.5、適用場景:
如果多個函式中有一些相同引數時,轉換成面向物件
class DataBaseHelper:
def __init__(self, ip, port, username, pwd):
self.ip = ip
self.port = port
self.username = username
self.pwd = pwd
def add(self,content):
# 利用self中封裝的使用者名稱、密碼等 連結資料
print('content')
# 關閉資料鏈接
def delete(self,content):
# 利用self中封裝的使用者名稱、密碼等 連結資料
print('content')
# 關閉資料鏈接
def update(self,content):
# 利用self中封裝的使用者名稱、密碼等 連結資料
print('content')
# 關閉資料鏈接
def get(self,content):
# 利用self中封裝的使用者名稱、密碼等 連結資料
print('content')
# 關閉資料鏈接
s1 = DataBaseHelper('1.1.1.1',3306, 'alex', 'sb')
2.6、面向物件三大特性之二:繼承
1、繼承
class 父類:
pass
class 子類(父類):
pass
class F:
def f1(self):
print('F.f1')
def f2(self):
print('F.f2')
class S(F):
def s1(self):
print('S.s1')
def f2(self):
# obj
print('S.f2')
# super(S, self).f2() # 執行父類(基類)中的f2方法
# F.f2(self) # 執行父類(基類)中的f2方法
"""
obj = S()
obj.s1()
obj.f2()
"""
"""
obj = S()
obj.s1() # s1中的self是形參,此時代指 obj
obj.f1() # self用於指呼叫方法的呼叫者
"""
# obj = S()
# obj.f2()
2、重寫
防止執行父類中的方法
3、self永遠是執行改方法的呼叫者
4、
super(子類, self).父類中的方法(...)
父類名.父類中的方法(self,...)
5、Python中支援多繼承
a. 左側優先
b. 一條道走到黑
c. 同一個根時,根最後執行
class Base:
def a(self):
print('Base.a')
class F0(Base):
def a1(self):
print('F0.a')
class F1(F0):
def a1(self):
print('F1.a')
class F2(Base):
def a1(self):
print('F2.a')
class S(F1,F2):
pass
obj = S()
obj.a()
class BaseReuqest:
def __init__(self):
print('BaseReuqest.init')
class RequestHandler(BaseReuqest):
def __init__(self):
print('RequestHandler.init')
BaseReuqest.__init__(self)
def serve_forever(self):
# self,是obj
print('RequestHandler.serve_forever')
self.process_request()
def process_request(self):
print('RequestHandler.process_request')
class Minx:
def process_request(self):
print('minx.process_request')
class Son(Minx, RequestHandler):
pass
obj = Son() # init
obj.serve_forever()
輸出結果:
RequestHandler.init
BaseReuqest.init
RequestHandler.serve_forever
minx.process_request
# import socketserver
#
#
# obj = socketserver.ThreadingTCPServer(1,2) # 建立物件,找init
# obj.serve_forever()
可以看一下原始碼執行流程。
2.7、面向物件三大特性之三:多型
====> 原生多型
# Java
string v = 'alex'
def func(string arg):
print(arg)
func('alex')
func(123)
# Python
v = 'alex'
def func(arg):
print(arg)
func(1)
func('alex')
三、 面向物件中高階
class Foo:
def __init__(self, name):
# 普通欄位
self.name = name
# 普通方法
def show(self):
print(self.name)
obj = Foo('alex')
obj.name
obj.show()
類成員:
# 欄位
- 普通欄位,儲存在物件中,執行只能通過物件訪問
- 靜態欄位,儲存在類中, 執行 可以通過物件訪問 也可以通過類訪問
# 方法
- 普通方法,儲存在類中,由物件來呼叫,self=》物件
- 靜態方法,儲存在類中,由類直接呼叫
- 類方法,儲存在類中,由類直接呼叫,cls=》當前類
##應用場景:
如果物件中需要儲存一些值,執行某功能時,需要使用物件中的值 -> 普通方法
不需要任何物件中的值,靜態方法
class Foo:
def __init__(self):
self.name ='a'
def bar(self):
# self是物件
print('bar')
@staticmethod
def sta():
print('123')
@staticmethod
def stat(a1, a2):
print(a1, a2)
@classmethod
def classmd(cls):
# cls 是類名
print(cls)
print('classmd')
Foo.sta() ##123
Foo.stat(1, 2)#1 2
Foo.classmd()##<class '__main__.Foo'> classmd
obj = Foo()
obj.bar()#bar
obj = Foo()
Foo.bar(obj)#bar
# 屬性(特性)
- 不倫不類
class Foo:
def __init__(self):
self.name = 'a'
# obj.name
self.name_list = ['alex']
# obj.bar()
def bar(self):
# self是物件
print('bar')
# 用於執行 obj.per
@property
def perr(self):
return self.name_list
# obj.per = 123
@perr.setter
def perr(self, val):
print(val)
@perr.deleter
def perr(self):
print(666)
obj = Foo()
r = obj.perr
print(r)#123
obj.perr = 123
#
del obj.perr
中國的所有省份,用面向物件知識表示?
class Province:
# 靜態欄位,屬於類
country = '中國'
def __init__(self, name):
# 普通欄位,屬於物件
self.name = name
henan = Province('河南')
henan.name
henan.name = "河南南"
利用屬性,實現分頁
class Pergination:
def __init__(self, current_page):
try:
# qwer
p = int(current_page)
except Exception as e:
p = 1
self.page = p
@property
def start(self):
val = (self.page-1) * 10
return val
@property
def end(self):
val = self.page * 10
return val
li = []
for i in range(1000):
li.append(i)
while True:
p = input('請輸入要檢視的頁碼:') # 1,每頁顯示10條
obj = Pergination(p)
print(li[obj.start:obj.end])
class Foo:
#兩種寫法相等
# def f1(self):
# return 123
#
# per = property(fget=f1)
# @property
# def per(self):
# return 123
class Foo:
def f1(self):
return 123
def f2(self, v):
print(v)
def f3(self):
print('del')
per = property(fget=f1, fset=f2, fdel=f3, doc='adfasdfasdfasdf')
# @property
# def per(self):
# return 123
obj = Foo()
ret = obj.per
print(ret) ##123
obj.per = 123456 ##123456
del obj.per ##del