数学建模社区-数学中国
标题:
Python面向对象三大特征
[打印本页]
作者:
杨利霞
时间:
2022-9-2 17:49
标题:
Python面向对象三大特征
Python面向对象三大特征
+ m' Z5 h8 H0 `% B7 h. L' d6 O/ Q, Y
文章目录
- ~5 U! V# Z. Q
python面向对象三大特征
& ]- b/ {2 `* {0 h- q
一、封装
, j/ E$ H1 i* Q
二、继承
, {4 D; O2 a2 y7 |
1.方法重写
" _. ~, q6 f+ L% K
2.object类
?4 ? s4 B) i& ]1 q- {
3.多重继承
+ H6 N, y/ h% w) h4 T4 @
三、多态
" Y8 e5 K; y' @2 G$ Z
1.动态语言与静态语言
0 ?& S5 R; \! Q6 _5 y
四、类的特殊属性和方法
; Q( N, \- }0 Y/ O7 y" |
1.特殊属性
2 c2 K( ^/ u5 ?
2.特殊方法
' j0 n5 P4 Y& u" m0 c1 x5 b A8 _
`__len__()`方法和 `__add__()` 方法
/ a4 T( |- t: D2 O6 R$ r) P
`__new__`方法
! J1 d, m8 X' Z7 N( o$ }% r) F4 \3 Q
`__init__`方法
1 j. N3 A$ X1 G9 h
五、变量的赋值操作
( Y8 ]0 ?, m$ N6 Y& c; J% D
六、对象的浅拷贝和深拷贝
/ }, f/ o" t0 I6 C$ t
1.浅拷贝
- e& t8 V5 T1 B% p0 n: B
2.深拷贝
. Y( e" C$ E7 r+ i" N! [% W
七、总结
% J4 |+ ?4 X) E! R% Y$ L5 D% ^4 ~
**`推 荐:牛客题霸-经典高频面试题库`**
[+ y" g* F% {
python面向对象三大特征
9 f# N6 w: J6 H, T$ }
封装:将数据(属性)和行为(方法)包装到类对象中。在方法内部对属性进行操作,在类对象的外部调用方法。这样,无需关心方法内部的具体实现细节,从而隔离了复杂度。
% f% W% e+ i- z( O8 O' D) W: z+ R' H
3 u v5 h& j, W U* s* Z D
继承:子类可以继承父类的属性和方法,提高代码的复用性。
7 N% D9 y1 Q+ }
6 T) @8 U% _0 L# z/ R) n; f* m" A8 e
多态:多态就是具有多种形态,即便不知道一个变量所引用的对象是什么类型,仍然可以使用这个变量调用方法。
7 T9 D, g* }7 e: T9 I
# X( \9 m: |. w& T% e' _/ Z
一、封装
7 E( A$ L0 }. n( v0 m9 N# D
封装:将属性和方法包装到类对象中,在方法内部对属性进行操作,在类对象外部调用方法。
0 n# A9 u. K! A% L4 v, W, r1 ^
3 [+ c$ j6 j) _3 l
代码实现:
3 Z+ Z" F+ r" I/ U6 ]
; t$ N) X8 k( ?- K
# -*- coding: utf-8 -*-
: Y: ?$ W4 j- L( B2 Q& S
#
@FILE
: demo.py
/ n0 r; _' H# Z0 A+ k2 @( P) O
# @author: Flyme awei
2 e' s c. U3 [, d) Q9 M( {
#
@Email
:
Flymeawei@163.com
1 } }2 @4 s% |3 ^6 [" f- M. X
#
@time
: 2022/8/15 23:27
2 P/ X# e, P/ h+ I
0 x; Y6 W8 g5 }4 V, A
% d4 X5 f+ X3 Y9 Q2 J2 P! M3 ?
# 封装:提高程序的安全性
& R" S r9 J% z% Z% k# }& K! H
# 将属性和方法包装到类对象中
/ |1 o8 p6 [) w1 v$ u8 D
# 在方法内部对属性进行操作,在类对象外部调用方法
2 w9 W' Y3 g4 `/ L& ~
/ a5 j9 |% n' `: k. i
class Car:
" k' U2 Q( B# S* M3 I) H) E, }
def __init__(self, brand):
5 `5 J$ L) L" \2 h8 L8 c
self.brand = brand # 实例属性
3 ^/ H. I. r( r2 k/ V, L: `
$ F ?# @7 _% Y
@staticmethod
B$ {' H, Y8 N# f
def start(): # 静态方法
7 v, Q9 x4 |! c* f% t
print('汽车已启动...')
5 B* C1 T7 _& W( s- r1 }8 W8 U
' _$ \% ~: _1 w" B' C% _4 z
* I+ v1 l* h- ]+ t
car = Car('奥迪A8')
" k5 Y3 y1 x) B9 D) H+ b
car.start()
/ O: M' _% }. g" y
print(car.brand)
. e5 z/ w% {% F5 R
1
& g2 M. b5 ]& a7 j
2
" f+ o8 T! h: M9 p) N$ W
3
. N, C1 s) e* ^0 i% {; R
4
7 s# k7 j% ?/ O, Y
5
( P1 Y5 e( i6 V
6
8 J8 i+ ?' J$ S
7
, S- k3 f0 D& _7 g! @7 ^( A. P
8
. |4 p. V5 o `/ V
9
# C, ?; D/ p+ t# E
10
- I! | |$ y$ i5 w& ]5 G
11
' @& {. Q2 d4 z% ~7 @- l
12
G5 S: C3 t/ [6 n, T' M7 d. s, ?
13
' I. x+ ]7 E9 Y( ^
14
& ?) |( p$ {( B* _2 _
15
. |$ E! G* V* t( t% q3 b
16
* n) `1 W6 t9 M3 }
17
5 U" q: i7 X8 J
18
, o( L- ?7 O- c& G5 ?
19
& I: F4 U5 m# b( [
20
+ E3 e0 f! v4 W# l
21
/ Z* q5 P3 M( Y; {" b0 K. Z& m
22
" n* Y6 r1 {# ]& P
23
# \: E0 ^: j9 P( V7 I( g
- {7 a- F1 `* C: I8 `$ p% x
* @/ H( F/ D3 U7 [
如果不希望实例属性在类的外部被使用,可以在前面加上两个下划线"_"
! s: l! G, ^* Y- Y7 ~7 Y4 o
# o. f, b7 z3 M, I
# -*- coding: utf-8 -*-
9 r1 u3 X' X* g6 A# s% N. Y
# @File : demo.py
. w& f3 H, z! b- q l% ]7 `3 \
# @author: Flyme awei
" Y9 I, F( p0 C4 M+ B
# @email :
Flymeawei@163.com
4 x% L# H& J H. Z" b F7 D
# @Time : 2022/8/15 23:27
" c" N( N! G5 J* n4 }9 P% D' b- T
$ P8 N! o6 s) F& K9 v
& n7 C/ s( _" e* H( a4 t; J
class Student:
2 R F+ i# V) e! G3 P. |/ T7 w
def __init__(self, name, age):
$ k7 o6 o) v1 V% r) z" {
self.name = name
- U. J* I8 u0 }
self.__age = age # 如果不希望实例属性在类的外部被使用,所以在前面加上两个下划线
! ^1 ?6 F/ _2 t4 a! @
3 ?* U$ s- W" J0 ~- i% n6 z
def show(self):
Z3 n: S x+ w4 y% s; q$ a
return self.name, self.__age
8 L* ?: T L7 H2 J
. r1 W+ O2 c. l/ x# Y& Z) l* ]
@staticmethod
# Q" ?% n5 h& Z1 l/ M
def eat():
/ A: O- `5 B: y
print('吃')
, W. ]2 J; ?) e% D- u5 m* g
, R5 d. S2 K7 @( @! Z
. a6 I7 |# t) P3 d. i
stu1 = Student('李华', 20)
: z! e8 Y8 C9 f$ a
stu1.show() # 调用方法
- K% W$ j5 P& A0 y: |$ {0 S
print(dir(stu1)) # 查看对象可以用的属性
* a- ?% p4 b P7 F
print('-------------')
9 B) C. d3 M3 q' ]4 o, e' ^
print(stu1.name, stu1._Student__age) # 在类外部通过_Student__age访问实例属性self.__age
/ Y% P* ?8 n1 G# N: q+ |3 T
stu1.eat()
. Y0 T' R: U m
( T. C) A, e; T
1
/ U$ k6 Y; V3 u- f( R) }# G
2
5 ?8 Q! ?8 \6 H- Q8 k& _) w$ V, d
3
! f$ j5 d8 s. m9 C) |! u
4
) A1 o- d7 @+ y9 [* u( X u
5
' m0 I6 G t0 H" w( L0 ~/ f0 L
6
/ R0 e' ?0 c4 r
7
* V* `! q. M( y) K+ A# b
8
; R9 u( x' @ r/ R
9
" P! D Q0 A+ w( U9 y
10
) p* @) ^, r2 a+ b
11
5 H, N1 e/ Q: a- E& X
12
$ v4 t3 I- ^: ]$ w4 o' g
13
2 }) j5 Y, ?) \4 c, ^8 I
14
9 J" e( k/ M7 T
15
0 C m% j8 l6 n
16
5 H9 N0 p+ h. n
17
# z4 S7 P) K$ q" c# C! G
18
$ D5 n. w& `7 |2 _6 L/ [
19
, i) X0 l3 S' ^+ }0 s0 _7 B
20
) I+ j# L' l+ p, N* C- K+ S: Y1 {
21
0 \- p$ q" y% o/ m4 H
22
3 {5 h( A+ @( u9 j8 F6 o9 B* R
23
; T, k) b) L3 Q, M" ]8 V% m- c
24
( J8 u: J3 {+ }' E' Q6 `
25
2 d, J1 r" K" [2 H+ o6 G% Y
26
3 _1 [1 b% p- K. [) S
* @* G8 E) J8 o9 }: Z
0 W/ h' o# P- L) y6 i
二、继承
& L. V- `+ K. \4 z: B0 \6 g4 Y
继承:子类可以继承父类的属性和方法,提高代码的复用性。
/ y Z5 d0 f6 `/ B2 u
如果一个对象没有继承任何类,则默认继承object类
' Q( B0 w- G% N+ y* ?
/ ]- M/ d! b* |
语法格式:
, r8 C% d% Q6 C5 r
7 t% h8 @' p% r% V% i1 q( |% T
class 子类名(父类1,父类2,...):
" i6 b8 l7 T) e# R0 d
pass
7 l$ a5 ^1 n7 n8 Q' i ?
1
4 p9 v, U# l9 v5 a; Z! s
2
( z6 [5 i5 @. P- e. @' N
代码实现:
5 D3 r6 q) V/ e" l6 ~4 Z8 J% W
4 \1 r$ ]1 i6 }2 o m1 _
# -*- coding: utf-8 -*-
% i! ]. M+ f1 @! q6 |
# @File : demo.py
7 t1 s) K3 C' Q+ [
# @author: Flyme awei
( y2 f7 E8 e7 r: r" z/ {
# @email :
Flymeawei@163.com
9 U" i. A7 U( G2 I$ E6 q7 `0 b
# @Time : 2022/8/15 23:27
1 O' n* }1 w5 @
# c/ t0 P! ^( e& m. e- d! r
$ U- X3 |& D) B' U: ~
class Person(object):
: u, V7 @0 f- j, E
def __init__(self, name, age):
# ^' L7 Z4 z) h1 x9 v
self.name = name
+ e% B9 U+ F3 P, h% }0 M* c d
self.age = age
' U( V# ~8 B9 s2 W& b. C
0 M- d7 g! f1 R
def info(self):
( f1 A! C/ D5 O* w
print(self.name, self.age)
. ~& l C, w" p2 K
' U4 L3 R& h# H# S2 |
* q2 {$ D- O/ D
class Student(Person):
* [5 x6 a; a/ v+ h$ X) r
def __init__(self, name, age, stu_nb):
# D: O. G+ o1 ^# \" t: e
super(Student, self).__init__(name, age) # 继承父类的属性
7 }& Q2 Z! n5 z$ N, o
self.stu_nb = stu_nb # 新增属性
( r* P T0 ^5 m; a5 `9 t3 d
; _+ z1 g! a' z
def __str__(self):
6 O7 V+ N4 u. U5 z$ Y' U' _! x
return self.name, self.age, self.stu_nb
& ]! K# N% O% x, F' ]; y3 l
% i+ N0 [7 T& b1 D6 k# w
1 H! v/ c H. a4 _/ U
class Teach(Person):
9 N' D( S. C. {9 Z) D3 t
def __init__(self, name, age, teach_of_year):
8 \9 m, q) [: L& G
super(Teach, self).__init__(name, age)
3 ^1 Y% s1 a- f# S/ a$ L
self.teach_of_year = teach_of_year
( ~ e9 w; B9 h2 J5 W
, ^% j! _- Q5 F3 j1 F1 g
* v( V/ i0 R0 ^( c4 l7 q
student = Student('张三', 20, '1001') # 创建对象
/ R" f/ b$ p: \
teacher = Teach('杨老师', 34, 10)
6 ~$ \6 U( M6 K0 ?& o+ e* k. j
% T7 }% l( n* O1 Z; H! P$ N: }
student.info()
& f) {1 R3 ?3 O+ [
teacher.info()
+ c5 _/ b6 f: m+ Z! J
print(student.__str__())
7 @4 I& t6 E8 V6 I
print(student.stu_nb)
7 ]% |2 [& J% w' ^* f
print(teacher.teach_of_year)
" _7 J1 Y3 D" L6 @* @' _/ q0 w
1
) _) E( J: H0 i+ A: |( F2 y
2
3 b2 b ^: w( N! |7 r
3
! b& L9 V& r! P6 p- P: W
4
! e5 r/ W; x/ [8 r$ C# D
5
/ ^# G9 P: m/ b+ P- F
6
: s$ ?: N H9 q, c d
7
# {5 h. a+ ~- p. }0 f" e
8
: y/ r4 ^, Y' t1 C
9
/ a% p7 M# W V/ g) E
10
+ P9 V9 y; y' Y1 H1 ~5 N
11
( g7 M) x/ g0 v3 |
12
$ P+ o1 P# ]& Y8 e! m/ S
13
% V7 l6 p7 b5 x
14
4 m. t ^) i1 K) @% h9 ~! n% d, H
15
' |& _& D' [! y" } o
16
6 A$ R! W- ~% t7 Z# z. c
17
3 G, P& U+ u# C" E; G9 v1 v
18
- ? J0 ]1 I! e: R6 k1 A
19
: F5 j4 z' A4 U0 U* I3 G$ Q% J
20
; d1 S$ l1 ?, A3 }1 e, {0 K3 G
21
1 j5 B' J( c+ k5 |: R% ~0 T0 r F
22
$ R/ _/ s3 o/ M9 M
23
} N0 `6 ~5 E& a
24
8 ?0 l9 h6 h9 w
25
6 ^8 ^# d% [& E1 n
26
; ] v( a3 r { u7 ]6 g- e j
27
6 [% q# S2 @; V4 _
28
( F3 w& e, Z' @3 w
29
2 j- b4 G2 v* J; |4 T- {
30
$ b! K% ~' z1 F+ Y8 O2 O
31
. l9 y; J$ j. X
32
9 z: j8 j+ c- u- f0 l
33
2 Q8 i7 {- X, a, {) K- C
34
, ~7 y+ ?6 ^2 W; }
35
. p! w# u# F' W5 K I
36
* D2 I% a) r$ }3 _) n$ k
37
4 G1 J$ N( W" v* `) I( H1 \2 g4 C/ r! b
38
4 P! a& m1 f6 n- s, r( d: {
39
3 Y/ m' R% }7 r, V' W
, Z) ]0 J3 G- G& O) R
; X+ b7 N9 }6 H
1.方法重写
8 |) I, p- T, c& L9 d
如果子类对继承自己父类的某个属性不满意,可以在子类对其(方法体)进行重新编写。
- I! k; i+ A' X
q! r d* D: q# @1 s% A# H) r) B
子类重写后的方法通过 super().方法名() 调用父类中被重写的方法。
4 _! U; T& G5 s! @$ D
" F9 Z3 j$ |& o5 B1 y8 ~8 X/ E
# -*- coding: utf-8 -*-
" Z9 m/ k( k6 n! ~; U C& b0 G
# @File : demo.py
1 v8 ?: F5 i5 Y5 v) j2 Z
# @author: Flyme awei
' B4 [$ M. l8 Q5 x
# @email :
Flymeawei@163.com
( a7 P; p! w2 X& Y" O2 L
# @Time : 2022/8/15 23:27
% h1 k. F5 B }8 ^% K5 ^
5 N9 z% ]' U. F* V: f0 c
! S, D9 X8 h0 ]- I1 V( N
# 如果子类对继承自己父类的某个属性不满意,可以在子类对其(方法体)进行重新编写
9 o$ A5 F, M1 q
# 子类重写后的方法通过 super()...方法名() 调用父类中被重写的方法
3 n1 g1 V9 `& c s0 d/ x
; W$ M, S+ K: B- ?/ r/ `
8 O2 U, w. ~0 F- T* Y \( d
class Person(object):
% F& ?0 M. A! n# u& x7 N
def __init__(self, name, age):
K/ A# y ]3 _; ]
self.name = name
* b7 i% Q" y: E$ U
self.age = age
7 n) M W* g$ }9 v1 V
9 l* e3 h& D" i p; U
def info(self):
- v7 v( P& k! K) m
print(self.name, self.age)
" T( C/ ]( t1 B) z5 s
& c5 h8 i2 _$ B9 a* J7 M; v
( E7 R, H9 u+ q3 Y7 z
class Student(Person):
# s1 f1 q( ?# W4 P7 M6 N" e
def __init__(self, name, age, stu_nb):
$ V X1 s; b: J+ n0 }. g$ R7 N6 L2 b
super(Student, self).__init__(name, age)
[( [- b: l* F' Z
self.stu_nb = stu_nb
) _* _) X; n# k( I( X( E( `
( K g! c0 o8 \5 G8 k/ Y. p* z
def info(self): # 方法重写
9 C1 d7 m' D( d2 u+ p! a, `
super().info() # 调用父类中方法
$ i" V. \3 j( {9 C# L8 v
print(f'学号:{self.stu_nb}') # f''格式化字符串
9 i7 z% b& l; ]% C6 _2 t& F
~* I) g+ B" J
! q; a/ ^: ~7 r
class Teach(Person):
# \7 _8 G1 i% \
def __init__(self, name, age, teach_of_year):
% o; _# S# B# w! r' A
super(Teach, self).__init__(name, age)
# ]2 A" w" R* _) T
self.teach_of_year = teach_of_year
; p3 j9 x. J9 i) H
- t8 R! M, \" Q) E |+ D
def info(self): # 方法重写
. p) R4 Z% ^; U! H! v/ p1 k" U
super().info()
: r0 |$ |9 t6 P6 R0 E& H
print('教龄{0}'.format(self.teach_of_year)) # 格式化字符串
1 ^$ l% I$ W4 j" `2 Z1 [
) T. K- g$ u" Q( \9 V
$ U7 T* o. ~9 s5 j- d
student = Student('张三', 20, '1001')
4 g8 G9 N6 `# x) N* t2 d! s
teacher = Teach('杨老师', 34, 10)
& |: z+ @: T2 Z3 T8 b
7 A5 y" s" {" V, W) e1 w
student.info()
! I& k. V3 Z2 Z7 n
print('-----------------')
' n" ]! I- B' i M
teacher.info()
) l* Q) u' s; V" W6 F
1
" {3 [' [5 g" F5 c; e
2
2 x9 b6 V! e3 M9 H- h; d# U! N6 ^( ^
3
; A4 B4 Q6 D' Y9 o& j0 y
4
% k# j, b) m6 w& M f
5
# A- ~. W* M" j- W9 D
6
1 k/ q8 o* S/ y: h. d; N% ?
7
/ U5 q4 x" ~ k$ i6 C8 G
8
% A V5 E7 n$ G5 o1 L
9
9 _' v' l0 E1 ~) K4 A% g4 J4 R+ h7 Z
10
1 h* L+ E3 C" c
11
M+ P7 T' ]& U
12
% ?) B8 E# }1 q' @3 l4 F
13
- O/ ^3 \" c& \5 g* @1 ~
14
: ~$ ^+ y/ n) N- X$ }
15
( N+ w; x2 E# H, t
16
& p2 X, y$ g3 i- F7 O
17
$ k! ~4 v0 z! i/ O$ E
18
& W( D4 Y. ?+ U* j. ^4 d
19
' m( `. `, y; F
20
8 m' w3 I# W1 p4 E
21
/ G( h6 R7 X" C% ?. F
22
: C9 d/ I) l! I C# ]8 m
23
; E8 t1 J; L! V1 A( N. I
24
. m, n' W: i" M6 l3 {- L- F. ~
25
, N$ `4 E: v: A0 Z5 y/ H1 x3 R- p
26
! ^. L) v+ H' D3 [4 P% x
27
# X9 R; _( `1 S/ Z
28
3 y; t. r% W }% ~6 H
29
# W/ a% e) B; U$ w% f! A
30
& W1 c! R. g. y$ i" X; H
31
, [ g+ L: p& x1 [$ L
32
. Q8 |, w; k. J6 N! D
33
& g7 i4 g. c: j8 }; T. |
34
: q Y+ m2 b2 H) H) N4 n( ]7 ?
35
$ ^8 @/ {0 u/ W$ _8 I
36
& r' B, d1 D. g/ U# U0 m2 _0 j$ Q
37
* ^- U0 ^$ x+ R }1 v% @. ?3 q. Y
38
3 z i' v" w: |- i
39
& B. y" y& d! Y
40
8 y/ g( y, y1 a2 }0 M: ~! v
41
9 N! F/ A$ [ U
42
3 o2 j1 g& Q% z: e# D0 m) Z( B8 V4 A
43
, L9 j' k r; |5 ^
44
, d; j& r! V4 r3 B( w2 R
45
% X6 W, [$ s" N9 ~) `5 g7 r
46
5 T2 c8 A* m' l' S. b }
/ B* B1 S" `2 Y M
. R" s2 w0 A( ` `4 J
2.object类
& |3 a0 m) `" ~, G' ^
# -*- coding: utf-8 -*-
/ |6 k8 {2 N; E! |, k( P) L' ^
# @File : demo.py
" v. D7 B @: d) I5 c: Y' O
# @author: Flyme awei
6 w u4 A! b( D: n( C% e
# @email :
Flymeawei@163.com
1 @) I Q# S: W8 i/ t3 g$ B& m9 y
# @Time : 2022/8/15 23:27
/ Y, f0 a* s I* C, ~! W4 t
2 H% _0 ?# P( t3 m- i6 s
- }; E+ W5 _: N# z+ g0 E" b5 f
'''
( |4 m; X2 b }! k" h* R# E
object 类是所有类的父类,所有类都有object类的属性和方法
4 {7 t8 }# O$ \, j8 E
内置函数dir()可以查看指定对象所有属性
/ z( N3 T; F2 g5 B3 t; B# o
Object有一个__str__方法,用于返回一个对于”对象的描述
- c$ @0 \& e1 w
对应内置函数str()通常用于print()方法,帮我们查看对象的信息,所以经常会对__str__进行重写“'''
7 s- s8 m' F5 d3 G* c: G
' t s% b: U) T G D
$ v; ^, H" k- X' l/ H
class Student(object):
6 ^4 G6 b7 ^& z% G& {
def __init__(self, name, age):
, D" j) w9 F# Q/ Q$ y
self.name = name
! k+ q! f, m s
self.age = age
& ~4 }2 i4 F. a8 ~) q
; e u1 x% M. j0 w8 F6 b; ?
def __str__(self): # 重写父类object中的方法
M7 w9 M$ q4 D# R$ N! Q
return '我的名字是{0},今年{1}岁了'.format(self.name, self.age)
7 W2 E w: ?8 B* s1 ~
* I0 o x+ ]( V) A
7 l2 v7 R8 S% m2 y
stu = Student('张三', 20)
' n9 g9 F, U% U8 y- X
print(dir(stu)) # 查看stu这个对象的所有属性和方法 从object类中继承的
( c" B( F7 G. Z& b8 N
print(stu) # 默认调用__str__()这样的方法 输出:我的名字是张三,今年20岁了
) I. \9 a( ^* `- k0 t, l( X. w8 j
: K- p. O3 B/ R. d3 n- _- g3 k
print(type(stu)) # <class '__main__.Student'> Student类型
/ w- t }' x$ P3 s* l
7 W3 q7 w! @4 ?1 |/ C( |, W
1
! _0 ]- \6 [" N3 L4 S/ f! W; C
2
5 f! ~9 b3 C: G2 W
3
4 c* O8 x5 o. A" F& J
4
$ h) `$ L) {+ x5 e
5
; D2 I8 q* j: ?9 K3 _4 M
6
, O* r, |/ Y/ r
7
2 {/ Q, ^: u" p- d5 c, f, C7 b6 W
8
: n" ~+ u+ _; V9 L7 c
9
% A* [$ _& b9 h$ u7 K
10
8 U/ n( j! ?8 i9 B4 s! b( N# B
11
7 T3 I N4 @. ^9 U& p
12
, F/ C+ \4 s: e+ l# s# D
13
# ], m- |4 @0 [% i1 P/ e5 t& Q
14
( J w, p0 @: a3 x+ G% H
15
" x7 c: L1 H+ ]4 K
16
' q n! R! ], c: T3 U9 {2 m) Y
17
. q3 M$ z' S3 G1 ?; O
18
+ W, v% M4 I+ w
19
( B# P5 x Y" C1 P; D9 h/ ?
20
: |7 e0 l2 H4 \& k) R
21
9 e! ]$ W# n8 \1 y, f8 O. h; n
22
* [! ` B- A/ C5 z$ H
23
% g. R: I8 \ ~( j6 f
24
# b, f: e- d) |7 K: |+ a% N
25
4 t3 `* I/ ?: F! O
26
+ @$ K4 b7 T2 z6 \! P; m
27
$ h' s5 H2 K; A& v. l: S6 h) A/ f1 R
28
, a m% d* B0 f7 I `3 u" S8 i
29
% T9 M$ d- ?8 x2 k: ]" S k) w6 h- `
5 G! C9 x' R. E ~
. Y* ~; ], |8 R' `+ p5 ^
3.多重继承
$ C- F# a* k' X. B
一个子类可以有多个“直接父类”,这样,就具备了“多个父类”的特点,通过类的特殊属性__mro__ 可以查看类的组织结构。
. @1 Z+ Q* y) M/ R! d
% I( x1 t4 N [. M" E
定义子类时,必须在其构造函数中调用父类的构造函数
0 Q& E2 \. G2 M: b" c5 w* O4 G
: E% R/ [5 z% _) d& [0 {
# -*- coding: utf-8 -*-
. A; S# d, f9 W& f5 f' V7 Y& a
# @File : demo.py
$ K1 [+ l( O0 y7 w
# @author: Flyme awei
7 u3 J" Y/ j5 l) o6 T O3 o' _
# @email :
Flymeawei@163.com
, l5 s( R5 e' {) E- J4 }4 `
# @Time : 2022/8/15 23:27
4 Y0 E# Z& Y8 m3 S5 U
* m# u6 Y3 Q) G9 G7 F
- h C1 V7 D7 }! L
# 多继承
( ?- G. y5 K" O
class A(object):
+ ^5 _0 l8 R* S8 Y
pass
& j0 t& C. [) y6 c
- B* x. F c1 d+ r3 O3 F* t
! M! B7 Q/ i8 s5 D" a$ ?- q
class B(object):
( @) C8 L. L$ j
pass
4 n. A2 Y* T* x* M/ p
( d4 ~+ t7 r/ {3 Q! w* D. e
& Z3 N1 }! _# Z( @
class C(A, B):
9 ~2 P' f, r1 [
pass
% N4 ?, `& v" t1 z; H
1
+ i! v3 D" m; m3 J% f( |
2
6 h! n1 y0 v" o/ v
3
. ^' X( ]; C( f
4
0 V1 J0 ]7 N7 e9 j7 x2 d. F, ]: s
5
2 r% e' H3 F' `% ~9 }1 I4 ~6 E+ d$ y0 H
6
. L% Z) N, l% L p: K
7
- D% o- l- ^: ?! O! D
8
1 G9 A* U* ~% R1 H
9
+ I7 W) B' s+ o0 t
10
0 K9 T5 s, _+ Y4 m
11
1 t7 T; y4 f5 o/ |
12
% c2 H7 a7 ]' k+ f6 m
13
# S4 q- T7 d4 a
14
$ [; y3 Q- h# S m9 m0 ]2 T/ x
15
1 [$ [+ b% W o# e. r9 H
16
$ \& q, {1 I' t; W+ U
17
0 M7 W6 c. {6 A1 H5 m% x3 X" m, h
18
( I6 u2 m& ^8 R7 h1 F& K3 y+ j
三、多态
9 y; l% v3 s. o) Z: l v
多态:多态就是具有多种形态,即便不知道一个变量所引用的对象是什么类型,仍然可以使用这个变量调用方法,在运行过程中根据变量所引用的对象类型,动态决定调用那个对象中的方法。
0 U2 h' a- w4 q' U+ M9 E$ y. p" e9 V7 l
8 v0 j8 B8 C, L: C! P& `# @/ O
代码实现:
% p5 T# }+ E1 T5 ]
* y+ p1 _* \! ^2 s+ ]
# -*- coding: utf-8 -*-
% t6 {7 r: W6 M' Q8 Q$ @0 f: y
# @File : demo.py
`$ \1 a3 o n! l) `
# @author: Flyme awei
9 c& a- `5 x+ b' h* b+ `
# @email :
Flymeawei@163.com
1 M3 K4 R2 R9 Q# q* t) j
# @Time : 2022/8/15 23:27
, {7 \0 @/ Z0 l4 {4 G
' y o/ O/ L8 O. \
, u( v6 O7 z7 H# T7 n% n
'''
7 r# a l C" }$ ]' @
多态:多态就是具有多种形态,即便不知道一个变量所引用的对象是什么类型,仍然可以使用这个变量调用方法,在运行过程中根据变量所引用的对象类型,动态决定调用那个对象中的方法'''
0 [" f+ s7 j- x
+ x# a1 r+ {* M
# 动态语言多崇尚鸭子类型,当一只鸟走起来向鸭子,游起来以向鸭子,看起来也像鸭子,那么这只鸟及可以被称为鸭子
, w' e5 z0 `/ @6 ^& p& r
4 U/ C8 a5 B" Z3 T+ M- D- J
7 o) Z }6 X. F4 G, x5 b+ v
class Animal(object):
, G2 c5 O: j; |# _2 b% p! Z& W- @
def eat(self):
1 E/ ^- M1 Z# l4 h* T7 o2 R
print('动物会吃')
8 V+ Q7 L& B! ], L* H0 J: s
0 r4 s' u- _8 Y& t# T
, D; p/ o) \" s2 L' J, H
class Dog(Animal):
% _3 O( `1 w. S
def eat(self):
0 j2 l4 f0 S, T
print('够吃骨头')
& E$ M0 W& L5 f) G3 Q% C9 u5 n' }& _
2 k6 g& F7 Z1 z% t, U' U
1 G% z( F9 U+ B: ?' {
class Cat(Animal):
6 U+ Q- b9 H; c
def eat(self):
8 _: J2 t3 G% Q. W1 j
print('猫吃小鱼')
" F4 Y. m( s2 G- q% A$ A' |9 F
3 [! k2 ~* u5 y; A% P5 Q; H9 A
/ Y- a( e% \/ B
class Person:
" e: o; W$ z8 q3 h
def eat(self):
* ^, j' Y" ]8 ?1 e, j' G
print('人吃五谷杂粮')
, B. d6 e( [- W' _ v4 n9 u: ]2 w
7 M7 F" a4 Y8 _. c( R
2 p9 W' ?. c' Y1 H+ c3 G
# 定义一个函数
" i& E6 X$ Q6 f
def fun(fun1):
4 H1 ^0 z* |1 p# s% V0 p3 m
fun1.eat() # 调用对象的eat()方法
5 T. q: X5 K) M+ n' ]+ W
) n0 g& P# D7 _. X& }
8 L8 j0 U( [0 x+ Q
if __name__ == '__main__':
. g- z- Z. P" `, e/ o
# 开始调用函数
E. g4 ] t3 H
fun(Animal()) # Cat继承了Animal Dog继承了Animal
/ S# j3 }4 J: C- E
fun(Cat()) # Cat 和Dog是重写了父类中的eat方法,调用了自己重写后的内容
6 u- m! p8 R$ H; f# X
fun(Dog())
. [( P0 p7 v& V" V: R( u
4 r, }4 L W& o0 o" u$ A
print('------------------')
! f) k3 q0 B: F+ j9 J: \6 Q
fun(Person()) # Person 没有继承关系 但是有eat方法,直接调用eat方法
5 u% `9 h. R8 G0 W! y0 |
8 e3 @1 f3 }$ Q( G. r' ?/ q6 D9 A
/ n' h2 m( V S, J# K. ]8 G
1
4 M/ N# Z, I1 Z+ d' L
2
/ T+ \0 Q. u8 J9 Q- r6 C* ^+ `4 S+ k
3
( J3 c* Q4 @) J' H3 U
4
# y3 E" V: \5 ~ j6 H
5
& @: [1 Q3 B( i; _: {- O1 K; ?
6
3 b6 e) y+ x! B9 y$ x6 J% y6 c% q
7
% t% {# N- {, w1 _* ~! s
8
) y2 W) G: E" S0 C4 S0 C" y
9
( C/ s6 e7 G4 O2 l+ \' Q# m
10
& g; [8 S0 D, D! ~2 N4 N) K8 o n
11
# p1 A# }6 \* y7 _
12
@5 l! G% ?) H5 }, ^% m- j
13
" M) ?1 X" S& g7 l+ z3 X0 q7 k
14
5 I' x3 X7 h7 R/ w9 d; ^1 k
15
# W3 N# ^4 c3 y$ {9 X3 K2 ?
16
/ W' w; e: J' G2 x& K' ~ ?
17
3 |2 d& {' R: A( I7 `1 A: m" P
18
9 {( `8 W, ~' X$ Y' z
19
J9 g. {; W4 L3 o
20
* P) f3 [: }: e, E
21
) w( @' _; C3 L* k! d7 w9 x [
22
) Q, c: A- F) ^+ A& b7 q$ P5 l
23
6 B k* ]# ?4 C" p
24
5 S7 X5 V8 ]) K/ p# X$ A _5 u% G
25
) `) ~# a2 N3 z
26
' `# z- |+ r6 U7 |
27
% @- V2 X/ Z6 k$ w0 u
28
4 F* p& ^# Z c, }* }8 S! z+ x
29
7 V4 V3 }( j8 K5 c* G
30
- i- r* n$ l" n% N/ F5 Y4 d
31
7 y1 \# Z& t$ I" l, o3 N
32
" g( x- i) D# @/ a: V8 }
33
9 m$ A& @7 N7 }+ ?) x9 T1 I% @- C
34
% Y3 Y- B: m: _/ c& \4 L9 T) L; Q
35
8 t4 ]* j& C+ I6 y6 b. }
36
c& P2 u# l* `0 W, \- s. V
37
+ {! n' {8 b' W: u
38
% p p* @2 A7 C+ {3 \
39
: T! \' b3 m2 N0 D. g7 Y
40
' A, @# y6 N1 Z: Y! c
41
) p i. [6 d. \ e9 R& v
42
" b' p+ d" o2 I
43
1 ^( |5 G* `( i+ b1 z( i+ T6 C8 U
44
, @$ F Z# S# E
45
/ j4 ^( b4 {8 _. s0 y; q9 ^
46
+ w* P' _* O( }$ i3 l
47
/ I" }3 d# U" r8 k
. k- Y& Y* w" m* v8 b: c* R
$ ?0 V4 I- X- l9 b' ^
1.动态语言与静态语言
+ J0 C" L6 n! m
Python是一门动态语言,可以在创建对象后动态的绑定属性和方法,
' t9 u/ ?$ ]) H" c9 r; M3 C/ W
& q% o/ E8 A1 B" u0 _! c9 o
静态语言和动态语言关于多态的区别:
! O8 [6 j, ^0 s# y
3 a7 V/ q9 L1 Z1 A( ~/ N6 @
静态语言实现多态的三个必要条件(Java)
1 O# u1 C) q! T) M2 q9 O D
1. 继承
4 Q6 s: O! N/ W: B% K9 H2 z
2. 方法重写
# c3 Q" O. f8 u( n$ r0 K" M
3. 父类引用指向子类对象
; |/ e8 @0 @9 |8 W( f. T7 p
, w" ~. H! O5 c8 W7 X2 q6 E# ~
动态语言:(Python)
. A* V/ b( z1 L/ w U6 `) f
动态语言的多态崇尚 “鸭子类型“ 一只鸟走起来像鸭子,游起来像鸭子,那么这只鸟就可以被称为鸭子。在鸭子类型中,不需要关心对象是什么类型,到底是不是鸭子,只关心对象的行为’‘’
# m) K5 M5 S; I, A5 _8 Q& T
& T: d- f* h7 C) M
四、类的特殊属性和方法
6 T. Y7 o3 ^5 i
1.特殊属性
7 S5 Q$ r8 Y G$ K$ Z6 e; d2 C
特殊属性 描述
" J* ~' T: Y- M& ^9 l+ g
__dict__ 获得类对象或实例对象所绑定的所有属性的方法的字典
7 Q. }1 I" S- j9 X5 h/ u- h
# -*- coding: utf-8 -*-
% t8 z& w! G& C6 w F8 K. }9 V
# @File : demo.py
, c/ ^ E6 [ k) C: M( A
# @author: Flyme awei
* h- q& P# J Y! v1 O
# @email :
Flymeawei@163.com
. W7 k W- t' H2 r/ e# U9 P: }
# @Time : 2022/8/15 23:27
# y9 }6 [5 ^9 E. J3 j) j
- E2 @0 P" U: n7 m) V* S6 ] Y
4 k. _. Y5 O: E5 T; F
# 特殊属性 __dict__ 获得类对象或实例对象所绑定的所有 属性 或 方法 的字典
+ ~ x8 Y1 p0 I+ ]5 |
class A:
5 [% O/ V' j7 v8 c0 [, R
pass
1 H9 h6 Q! J2 s3 B* |
" H& F1 f- ^3 _* |6 l, u
, x( J3 D8 [, I, |# n
class B:
/ v0 u0 B- D/ d7 | F ?& j" X T
pass
% l8 B9 Z7 u) s5 E- q
9 q& g- g- b. M
. I) h' N7 y, N/ N+ I+ r) Q1 K" i& H
class C(A, B):
6 J3 _4 A, c! L/ B9 Y6 r, g
def __init__(self, name, age):
% N2 ~ ]3 Q/ w# s! N1 G
# 实例属性
8 s0 w; x! Z9 D
self.name = name
* h6 A) n' s2 t7 L1 u. H
self.age = age
; s; n* r' K4 ^* e
: Z* s: q4 h8 u. K
9 H4 u# U6 ~8 i: T# l" Y& t1 J
if __name__ == '__main__':
$ L8 @6 P; T3 h) j0 `
9 w J/ Z0 n; U m/ J; _
# 创建C类的对象
+ B% }! N( }4 @
x = C('Jack', 20) # x是C类的一个实例对象
8 X! F% C. h4 y3 B4 D
5 j) h8 T: X5 b2 }( p
print(x.__dict__) # 获得实例对象属性的字典
9 N8 p) D6 e+ h# a/ W6 o; F% P
print(C.__dict__) # 获得类对象的属性和方法的字典
) M- e7 \, v+ H' q4 |) n0 Y0 c
print('-----------------')
" I3 P% M& h/ |' q6 I% T
0 A( G+ b, A) d+ ^+ `( b
print(x.__class__) # 输出对象所属的类
+ W. ~9 g# q$ v3 [
print(C.__bases__) # C类父类类型的元组 (<class '__main__.A'>, <class '__main__.B'>)
& M |; E) F/ @* J5 @
print(C.__base__) # 类的基类 离C类最近的父类
7 R1 L2 v; v& U
print(C.__mro__) # 查看类的层次结构
7 H8 D! Y( I" W# ?- M
print(A.__subclasses__()) # 子类的列表
. ~2 U% g2 J8 c
' o6 Y- V* a, Q% C
1
3 t0 h, Y: L1 [8 Z' O
2
1 b% D1 E- U! V! x+ U
3
9 |; w/ X3 E. t7 u# M
4
0 G% @% X( S7 @( I, B& I
5
) \3 S# H1 @. }6 r* Y
6
6 m) E' m* h: t# W8 }% a
7
5 c$ ?( w; _- Y( J U* v
8
; Q2 i: x) V) f; I
9
% B6 ?7 [$ E- h
10
; M' ^# n' ?9 i! ~* r( [
11
! K' o4 W6 ]/ O: o
12
8 _7 i6 r2 o: g
13
+ T( X& a8 b! `* N
14
$ P+ a6 f7 }- v: `3 X; B; J
15
" c |6 | a& n8 k0 f' l4 c
16
- @8 q$ j- H& u* @, ? v5 e
17
# I! O0 Y; n4 v- N0 q+ }
18
: f+ l6 m: b) k, f3 ?8 ~6 X8 y9 R( K
19
. W3 d$ j6 q: }/ s* t2 _6 l, [& u( ~
20
. Q; g3 U, P" h4 D1 _
21
3 A$ B: t0 [! W; x4 g/ K* N
22
7 Z3 j# [: }% B. N# c! j) K6 m- R
23
9 Y5 a, H' R+ o" I
24
- b' A/ C( \' X$ K
25
8 H( ^9 |2 W# Z
26
3 [: f' s! `5 u
27
8 \* l6 f* \% k7 w/ q0 N
28
2 c# p% \8 W- k* V: b/ i4 t8 _
29
% P0 P9 z; K* u s* P+ f, Q' C6 ]
30
7 u6 G! q1 {+ L2 s2 r9 y7 g |8 P
31
' W& p- w. U2 @3 X
32
- N5 \+ |) y) _" |9 w1 u: q
33
8 T$ [0 ^: R% S
34
N/ W+ ~" d& E2 [
35
( m$ G6 ~$ i$ [! L& k" [
36
2 V2 G) g# n& U& n: I$ J' ^
37
- m$ D. q5 G/ ^1 \0 l
38
1 v/ }* C3 f% Z3 s
2 k& N; Y9 z2 e( H. J( j
6 R- y9 }& [% L
2.特殊方法
1 Z" T* k$ Q5 J& T" t- X; Z: v
特殊方法 描述
4 y; L/ g5 C* Y1 p+ p0 [5 c- h
__len__() 通过重写 __len__()方法,让内置函数len()的参数可以是自定义类型
, a% @, C5 v9 b4 l" @: S2 w
__add__() 通过重写__add__()方法,可以让自定义对象具有+的功能
' _3 [$ |' |; g( Z6 `
__new__() 用于创建对象
+ Z* o, |4 S6 X1 M: t
__init__() 对创建的对象进行初始化
6 j. j$ I4 T/ ~9 C' C0 D5 w
__len__()方法和 __add__() 方法
5 u6 D! `. y" L4 S1 M( T. M
# -*- coding: utf-8 -*-
, N M5 s6 P2 t
# @File : demo.py
$ K1 Y3 C/ x' D
# @author: Flyme awei
" t; m! D. [% n* ^
# @email :
Flymeawei@163.com
. M6 y) x4 X* y% w3 s v
# @Time : 2022/8/15 23:27
$ @; s3 E2 \6 Q' x1 V
1 _- R, d, P; n( L- f) G: x
3 w1 P; Y7 I$ e x2 s7 n
# 1.特殊方法 __add__()
. A9 p' K& G. a( z* t4 G
# 通过重写 __add__()方法,可以使自定义对象具有 “+” 的功能
* T- F' n( N* ~" g. A
a = 20
* V; E& e2 ]( x: @& x, ^4 M) m% l
b = 100
, ]2 h S. d* M% L' b
c = a + b # 两个整数类型的对象的相加操作
: J) G1 e4 E! {8 [7 L7 q; `* T
d = a.__add__(b)
, a! o+ d/ N4 O5 T6 }
print(c)
9 `; D- _1 w0 Q! e
print(d)
4 o% p3 `$ w; s k8 x/ V
$ L' }9 C2 T4 w5 j
T- u5 f- G7 [( E5 l$ k8 A8 m7 n
class Student:
$ r$ b) i8 ?* y9 f1 [: }
sex = '女' # 类属性
8 U0 m6 Q6 r- {( X4 r: @3 b
$ f0 n$ l0 L- F: E$ @
def __init__(self, name): # 初始化方法
6 P% K. L; m; F! W" L5 o
self.name = name
* [! L J2 U! p- S- r! x Y
0 D0 n% c$ q2 E: Z! f8 J; D
def __add__(self, other): # 重写 __add__()方法 可以使自定义对象具有 “+” 的功能
* n0 z% \! Q. o$ m& O
return self.name + other.name
% r4 j5 H8 Z) o. _' u, U
; V$ e& \, D$ T c
def __len__(self): # 重写 __len__方法 让自定义函数len()的参数可以是自定义类型
% ^0 R1 }7 b& K1 p
return len(self.name)
8 v2 ? l+ _% D+ A
5 z0 N5 {4 c2 I& S0 A. D8 ?
; H# R1 l+ S4 ~ M. N
stu1 = Student('Jack')
) a2 x2 Z9 F2 @- ^+ Q( Q- U. ~, w
stu2 = Student('李四')
& F, ^0 y! w0 R- b
s = stu1 + stu2 # 实现了两个对象的加法运算(因为在Student类中 编写__add__()特殊的方法)
0 @$ V4 c' y' ?( [! J
print(s)
/ H4 X0 P* O( [
# {- z0 L* `/ t8 [
# 2.特殊方法 __len__()
& T4 T! W% I8 f. [* b
# 通过重写__len__()方法,让自定义函数len()的参数可以是自定义类型
7 a8 h# o0 v# s, K- B* f
lst = [11, 22, 33, 44]
( T4 T8 Y, a; H7 D: [1 w" m
print(len(lst)) # len是内置函数,可以计算列表的一个长度
0 |0 f2 ^- e; e: K7 i
print(lst.__len__()) # 特殊方法
6 c2 G9 p/ f9 W/ Y: X
print(len(stu1))
3 C2 E% h6 \0 {9 s# D3 \" a9 f" l
1 o4 x5 G/ Z8 U, u$ @6 b6 A
1
. O. d( I" B( Y9 l0 j t' G
2
% L0 o( R7 \6 p# g a. P1 ]
3
5 {& {8 i+ p4 g8 J( \( M
4
* I! \/ A" S% {$ _
5
9 s% Y9 i$ c5 \* P% y* R8 m
6
# O* K" s' O: F# K0 D
7
) \ o3 d6 _3 ^9 s
8
8 m- z6 Y' \6 N$ e5 \3 s
9
# S' y& { I$ U6 |2 v3 @8 |& W
10
$ T% F$ S& X9 |7 x
11
& s4 K2 w# }$ P3 p3 T
12
" j+ F) z- @) L& b% l" M
13
, o1 r9 \- R& M8 z" W
14
+ d3 A8 {: m0 V9 [3 \
15
" L% E3 H1 I# t0 p( q
16
- r9 J; z% }0 Z6 U7 v- M8 W
17
8 D% d& \7 O8 {2 z, n4 Z1 a: d
18
* y, u& a( I& _8 g/ e* N
19
& _* b0 G G6 \9 F
20
& R' a. d/ @! E9 y& D7 V
21
5 x6 p% q: X$ D( i1 l7 L& Y5 @! U
22
" u; Q+ W6 e; l- V& x& i
23
. @8 U* b5 |" n4 v% s
24
! } K: O% l, u, H' C
25
" d. K% E' \+ M* ?8 e
26
. H7 ], j m1 R$ s( f
27
. \- z0 J8 s, J" X4 Z
28
5 f. e& w1 D2 j! u! `) r" \6 n
29
. A. x" t; N" Y3 a5 k/ W
30
7 h m) z+ Y/ z
31
- W6 p2 p+ P2 o" e$ G
32
. F+ N$ V8 G$ c
33
! O; j6 l5 a( X
34
4 h8 e5 z- b' e) ]
35
5 }/ f# R: n* e! j. v
36
: N0 ~% ~+ @% F: ^$ ?" j
37
2 w5 N! b* w) ^9 f- i
38
9 K% N8 N1 [% U. b2 @
39
% R: O2 q$ E) P0 x
40
* w: g8 M" J4 X+ c7 _) A6 x6 G
41
& a/ ~" u! T6 m8 M$ x. d2 i
42
: f& T. S6 N3 }8 g
" C* l$ D# ~4 S
$ F# F7 P) U5 ]( B& a. C
__new__方法
, z `2 E I) H j
# -*- coding: utf-8 -*-
% f% S$ x0 _" b% T
# @File : demo.py
2 d/ e' p# K( q Z9 }
# @author: Flyme awei
- h' n5 L$ A0 y! o+ z6 a' q
# @email :
Flymeawei@163.com
9 `2 `; \* c: Y4 a
# @Time : 2022/8/15 23:27
$ {8 F# l0 z: v1 H+ P( X
9 y3 B, i3 \3 Z
+ J6 ^9 s2 V& ~- x
class Person(object):
`2 H5 o8 [, n
def __new__(cls, *args, **kwargs): # 创建对象
, S' q: P5 R+ {$ E
print('__new__()方法被调用执行了,cls的id值为{0}'.format(id(cls)))
+ Y0 B" [4 E% X
obj = super().__new__(cls) # 创建对象 obj
( u+ C6 N6 U. ?5 X J6 S
print(f'创建对象(obj)的id值为:{id(obj)}')
" Y. a9 K: Y) E, ^/ q- Y
print(Person) # <class '__main__.Person'>
' C, R# l- e& f( @! h6 N' }
print(obj) # <__main__.Person object at 0x000001C8B13D9CA0>
- E' B. I6 ~+ d2 _% f" a
return obj
+ l# p3 v& ~" W+ Z" ~. L% W
; _1 I: s4 g, |& _; K
def __init__(self, name, age): # 对对象的属性进行初始化
' z& @. G: I! ]* n# i6 v
print(f'__init__()被调用执行了,self的id值为{id(self)}')
, q: P" n1 W" z& P5 ^/ L, J) c
self.nane = name
4 Q! c6 z. A0 p% _
self.age = age
1 w5 c7 L R% d" Q2 O% [
. i0 P3 j0 k+ w# ~5 l% |8 V" z( H
$ |" O: a% w, J! D8 w) ~
if __name__ == '__main__':
- ~$ `# @& m# m5 S- j
print(f'object这个类对象的id为:{id(object)}')
# N* k6 \5 p. P3 }
print(f'Person这个类对象的id为:{id(Person)}')
+ b2 v% V. e5 m3 Z
0 [+ h K/ w8 n8 \) J" y0 x4 c
# 创建Person类的实例对象
# C, N0 @. c5 I2 S7 Y( b/ d' [
p1 = Person('张三', 20)
9 ^5 H8 K l: F
! e" [1 U- \! d
print(f'p1这个Person类的实例对象的id为{id(p1)}')
7 @3 }% ?$ [# D
1 j* p# i; w* ?. u- w
1
: R T+ f; ?- s' Q. ]. o" H
2
9 Q) Q$ a: q, S# I) K
3
1 l3 H* P! j5 y c: k1 K
4
, p/ \4 Z" R: @) O; g/ O% u7 C
5
4 R$ ~3 Z7 ^ _2 x2 F. q5 K
6
" g8 {1 ^4 H1 W6 G0 F# {
7
2 V" j" R5 L$ Q$ q
8
+ @6 _, a) _& h9 `. R* z7 B
9
3 V( [: n6 W- h7 T. g8 ]
10
# ?& |& k0 z5 Z3 X* C0 C2 I
11
1 i9 f) k3 u* [1 `# x
12
; }6 O& ? {% e
13
0 i E* r9 q9 A8 _% ]* I; X
14
0 X3 o: I, C1 C9 L6 a" J7 P: V
15
) j4 Q/ X! p# s h3 o7 C2 J
16
, R/ ?; |7 A" h1 {* N- U
17
: H/ M9 M m! @4 t- y5 o. g
18
- ^8 `6 I. ^! H
19
! X) F. K1 O+ k
20
$ w- h: i6 W3 c, i
21
2 t: p8 J0 F2 e& l- P
22
) b4 ~1 j& E) t
23
: B4 l7 e% }# C1 h
24
4 K k% t% a0 |. g% z) l
25
7 J3 t# f- |# \9 H7 [5 k O. ]8 M: o/ s
26
" `. ]0 z/ t, g) y6 p2 ]% ?
27
0 j7 |5 ]. h, X. h' s9 ~. t5 D
28
2 Y: `! I! N' V1 ]
29
. m x* Z% }8 M# l( s
30
( B3 j7 Z3 c6 e7 F+ A }, f/ F
31
7 S- A8 l; a+ t( Z9 ~
( {/ z, s/ Z ^$ H
$ I4 T8 }; j2 \% n- T& @& b
__init__方法
5 |1 d( T2 v( {
# -*- coding: utf-8 -*-
: S: e" S" Q2 \
# @File : demo.py
9 I. J" t& C- ?
# @author: Flyme awei
# W2 E( g9 ]2 H6 N" f
# @email :
Flymeawei@163.com
! x Z$ L" q+ w/ u6 d) f8 }
# @Time : 2022/8/15 23:27
' _3 f* t& M7 @" j
+ a k$ K4 V( _$ z6 [4 O) V" T
9 ^' C1 u! `" D! Q @9 h$ I
class Person(object):
, U- Q1 z& f" Y, R, t6 N
def __new__(cls, *args, **kwargs): # 创建对象
5 P2 _3 x1 b4 B3 j' J7 H
print('__new__()方法被调用执行了,cls的id值为{0}'.format(id(cls)))
- P; o/ ?/ `$ f: t$ m
obj = super().__new__(cls) # 创建对象 obj
, w* r9 g& A1 Z5 h- Z. q
print(f'创建对象(obj)的id值为:{id(obj)}')
, f% c/ ]2 {/ `- x& a* {
return obj
8 F! a% {- F& C5 f
$ U. _- q7 e, @9 f
def __init__(self, name, age): # 对对象的属性进行初始化
0 h! z; S; Z% |3 a2 I) r
print(f'__init__()被调用执行了,self的id值为{id(self)}')
& X; V+ i4 M" `3 G4 ?% {, q
self.nane = name
, X' }; ~8 C( Q+ D4 L3 y+ M
self.age = age
) J- b1 Y. b) @4 c9 C' j
: S) M* t) f5 Z
2 U( W$ f3 R8 M. W3 W
print(f'object这个类对象的id为:{id(object)}')
6 s7 n7 K; i3 o
print(f'Person这个类对象的id为:{id(Person)}')
. W7 ~/ ?$ T' C) y: S+ n$ u, I4 X/ O
! ^+ f; W( V' U
# 创建Person类的实例对象
2 o) s3 a! v r: w7 P: m( D7 ]
p1 = Person('张三', 20)
- s- b, x! ^3 E
print(f'p1这个Person类的实例对象的id为{id(p1)}')
! p' Q7 b& X1 C6 L/ n* m- z# p4 `' F
: Y# c G6 e' B& u- X, [
1
. k! a9 S' |7 i- v& N
2
/ [' y& O2 m1 T
3
! W( D5 `4 @1 e" u' @- e' a3 D
4
1 \$ ? T& u$ {0 j5 n, q* Y& S" Q4 G# r
5
4 X, H. V# j% O: e2 A" R! Y
6
+ U2 t h3 H+ j2 [- l. F
7
0 q4 K' b- G* _$ p; H2 h6 y8 X: _
8
$ ?4 t+ Z0 N: c+ }- i
9
! D" g2 B+ v2 a7 h S6 o0 d
10
p8 g5 Z; P8 n) f9 F7 x
11
; T2 ~( Z( ~6 i, O
12
6 [3 U1 T4 h6 U7 B$ u
13
) b7 @$ M: ?0 ]5 S0 ~/ [
14
( b+ p6 W0 X0 }+ k5 o" a
15
6 z. {, t: y. j( A. J, \
16
# L+ V; X: D( p4 \; G
17
_/ B* [. p- y% f
18
* u. a9 q* |8 g A
19
3 @ M, K6 e9 r" n6 ^/ Z
20
[" N3 n8 O h$ _5 S! F. D' \/ ~2 F' {
21
; p9 W$ U9 G+ M8 w3 G( q2 |
22
3 Y: k( q+ y2 Q9 D) I- c8 o, f
23
/ m/ p+ T1 d1 A* F' a8 D
24
& r3 [5 g) u/ Z7 K; G5 g, I4 R
25
5 B" i6 Y% b" F
26
9 _8 ]3 w, K6 d# D
27
( k. }* V4 ~# D0 Z+ _/ O
- `/ l( B& w% N: V# B
H3 W6 j$ C8 }* v* @4 T t
五、变量的赋值操作
# E8 O A6 k* p6 w% b( W! C
只是多生成了一个变量,实际上还是指向同一个对象
- X0 u# ]1 F+ w7 y" Y. V$ T4 R
, v3 U' Z8 L0 f' V
# -*- coding: utf-8 -*-
, |, R- Z8 r I. p* F- t4 x9 r
# author : Flyme awei
& H" e6 D: @: L7 {1 {4 ^ Y! C
# 开发时间: 2022/7/1 15:32
( A% m9 G$ g, D' c0 q4 f1 a3 X% W
& F2 o5 E. ?- W6 Z! X/ s/ r5 p
class CPU:
4 c+ |0 R# D, ^: _, G* b
pass
A, k r% t5 D! ~9 [) |7 b
4 A( G' J# o& O1 t7 A2 O3 k
0 w( C' p1 \. \9 L8 F2 P
class Disk:
Z9 ~/ a) T& t
pass
" |% |7 }. f$ a8 \
% X, P. |' ]" t9 C. P# L6 Y1 g
; R$ s1 f3 s' Q; n* M9 I
class Computer:
- A7 F! b; t3 d7 A" d6 k
def __init__(self, cpu, disk): # 给对象的实例属性进行初始化
: D1 |3 U _5 ]/ O. q
self.cpu = cpu
; m2 B; d! Y8 ?
self.disk = disk
. y2 N8 I" p: X
1 W. L) i+ A: }# Q& f
* x6 O3 N/ C: X- H" k# h ]
# 变量的赋值
& }0 f$ ^# Y; u- \$ w0 t
cp1 = Computer(cpu='CPU', disk='DISK') # 创建CPU类的实例对象
; K7 k! H% y& c* p# x! C. u) h
cp2 = cp1
6 t+ E: y% E t: `& I* J2 Q" y/ `, \# o
# 变量的赋值,一个对象的实例采用两个变量存储,实际上还是指向一个对象
- Q6 J9 ~- }8 \8 k7 D, Q
print(cp1, id(cp1))
7 z' K% l+ N4 W
print(cp2, id(cp2))
* o$ t: V# d9 F, F8 Y E- N
. ]+ U* Z4 O5 s0 s4 ?) E
1
- ^1 W \& w0 B4 y0 R
2
/ h9 r( [5 w1 w, W+ d) v- w
3
4 k8 [# j2 @! A
4
3 R p0 R, P. Z/ ^1 P! k
5
3 L/ `) N1 v% j3 Q1 e. K
6
~( u/ k( t/ J- K9 {' }
7
8 S, W* K; S0 G+ _1 j4 W# K) r& \* Y
8
/ H' o4 h/ @: l. d9 J
9
- ?" N% D4 k8 x/ b5 ]0 J! i
10
, h" } M- h8 W, C# R
11
1 X' Z) H" A% M0 M9 W2 ^ I
12
8 x9 @" G- X% l' P
13
% B: R/ S" j: c' K1 U
14
. L! k" ?! f% w( g
15
7 M% v: K: l9 c# m$ L
16
- z; Q2 V( [% J J4 I, Q# r
17
0 E8 [1 l8 O9 l2 m; V- M) ~! |# ~) M- \
18
* z3 ~! ~6 R! S6 ]- y5 G3 ^: D* e" i
19
% r7 p, s5 \9 n2 `# B" l' h% y, a) S
20
: @3 ^/ p) H& |# T) g& E
21
! B" v0 w& m" M" e' ~5 n9 [, F
22
. p$ v) a/ V$ O4 u: v. T
23
+ l' {7 ]+ R! g
24
7 s/ }7 M9 E( k* j G2 |- l
25
) o7 G1 _3 y# [+ q" z8 P, k
* U! w V0 z% n1 Q+ E9 y$ S
+ I+ |% [( U- }# W& h3 U; j6 z
赋值(=),就是创建了对象的一个新的引用,修改其中任意一个变量都会影响到另一个。
% C5 w4 L- H3 ^+ Q+ @2 z) r3 \
6 ~' w. R5 V2 r0 w: b
六、对象的浅拷贝和深拷贝
( J3 o. |; e" l# X% N- h
1.浅拷贝
2 y5 `$ _) B* q i/ E
Python拷贝一般都是浅拷贝,拷贝时,对象包含的子对象内容不拷贝,因此,源对象与拷贝对象会引用同一个子对象。
& ^; f8 F! ^/ k+ ~' E. C- ]# D
! z: _9 n9 v- g$ h
# -*- coding: utf-8 -*-
& Y7 _& a! C, O( V1 ^$ ^
# author : Flyme awei
q2 h) ?" F; ~0 N
# 开发时间: 2022/7/1 15:32
5 [0 `: W( `; A8 |+ Y+ |5 R: E* |
/ m! p# }* b' A* Q0 I2 E1 a
import copy
' ]1 ~% ]% n7 `7 Y
6 Q2 M! P$ b3 T; X9 n
! u! d) }- k8 Y9 L
class CPU:
7 Y- B# @2 ^$ k% X, k
pass
5 @+ x2 c& I5 c( \' A; s) ^; c5 K1 O
5 O% F( ` a$ `* A1 H+ X: D- B
$ [7 p( r+ A$ g
class Disk:
' {, q% ^3 g% t/ G: t
pass
1 u! t4 K2 b( C3 d/ ]7 x
* Y; r' P; M6 N& G
D$ t1 W* L9 I4 M4 a
class Computer:
% d+ p0 Y( \- a! T
def __init__(self, cpu, disk): # 给对象的实例属性进行初始化
, k$ p8 a+ g4 l9 [" I. f( ]3 b
self.cpu = cpu
4 f0 N/ H. j7 M, J$ G9 q, J
self.disk = disk
9 b+ t5 W. o9 M& i
& M% E. L5 F' M# l3 ]
' ?3 O9 S2 l+ @, h% C
cpu = CPU() # 创建一个 CPU 类的实例对象
. g2 s0 }6 Z" j/ x8 |9 v; n
disk = Disk() # 创建一个Disk 类对象
- M6 d% [: o4 S+ _8 k; }7 c- X
computer = Computer(cpu, disk) # 创建一个Computer类的实例对象
4 J1 W. E6 Z# c4 h0 R. z9 g! d
d( w) e t9 C
# 浅拷贝
7 r' S+ a5 ~4 t7 W% T/ f, E
print(cpu)
! _# o& V( ?( P8 ~
print(disk)
" G0 m2 G7 s9 ]
computer2 = copy.copy(computer) # 子对象不拷贝
$ b+ i1 e+ y% N; |4 [) ?2 B
print(computer, computer.cpu, computer.disk)
W: W) b0 n# F! K& p6 Z+ v9 g
print(computer2, computer2.cpu, computer2.disk)
' `/ n6 G2 W2 \
/ z% R: Y3 f' _3 r' y0 G! b, P
: s& n0 f' D. u+ l, N7 ~; L# I
# 类的浅拷贝:
. R! F2 O& c) J ~- E+ x
# Python的拷贝一般都是浅拷贝,拷贝时,对象包含的子对象内容不拷贝
1 w/ @$ l# W7 v, X
# 因此,源对象与拷贝对象会引用同一个子对象
9 Y5 k' }3 c z% }7 x
1
% f% q; T4 q r0 c+ \4 V
2
5 l M8 s. F) _# a2 N/ H
3
" y ]9 @; Z8 A9 P i8 t' b" L
4
3 J# z2 h+ `1 X" J
5
0 c# y2 l! }' T* e! T
6
% R w5 V4 c, U( o4 p ^
7
% B" Y, A% D6 C$ c! R) v
8
9 T5 b* u& a, K) q- h) P! T( ^
9
9 z7 _, L: Q' V' z2 E2 {9 p
10
9 \0 F$ I, D. v8 n1 P* d
11
9 E. x' Y1 F2 I; M& L
12
/ f# N3 x! s+ l6 _
13
7 ^+ k# H& H& O
14
' _+ G4 c% y% H! I: c
15
/ D1 B9 f- }# W
16
5 k/ g# h/ o, X% C# n) c0 }
17
. c3 F' u# X0 C) ]$ W* e+ z
18
8 L- ~4 i; _! l
19
* h! p+ x4 L5 \
20
$ G6 A6 ^7 D6 I3 n
21
" j' e; ~6 M9 ?4 G' {
22
2 e6 ]" ]# t7 ^& w7 V
23
" c- t I; {' E
24
+ ^( H' Z# R1 _0 U o0 J3 p5 a/ Q0 Z
25
! ], e8 c0 f. Z' V: R
26
& y( ^9 G! z6 k3 Y* K$ @! E8 k6 x
27
1 N- ^ u( W1 H% d1 ?
28
& o% a4 U2 K8 }9 @
29
, y- r$ {+ Z$ m5 i1 V y/ b! f
30
5 J% L" u$ u) B0 e6 m9 o
31
& ^ \0 T$ S8 r- j. E0 a
32
. \2 c: v- f( m' R$ q
33
0 U" u9 Q; C9 A6 E0 A. k x2 b. W
34
4 I4 J d# y" g! s8 F. E
35
j5 U% A/ T4 X p, n; B
36
$ v5 t4 Y) Z! n% e( B3 u
1 [# a/ T0 `, Y$ D, l; }
, f. R, ]/ z5 p. n! e4 Y1 `0 o
浅拷贝:创建一个新的对象,但它包含的是对原始对象中包含项的引用
# D3 _$ [$ r* p+ ?
(如果用引用的方式修改其中一个对象,另外一个也会修改改变)
/ G$ Y. ]! W; h3 _
/ X$ b: N. V6 x+ |: s% @+ H: T
哪些是浅拷贝:
0 w7 v/ E: e) t
* v) a8 x- X* v. i/ z- R1 v* P6 |
完全切片方法;
( W5 y, d8 c- Q4 u# j4 b. }& v0 a5 r
工厂函数,如list();
4 D( ]/ D( Y/ t1 `. B' {) Z
copy模块的copy()函数。
' K. z. H; ]: ^* V
2.深拷贝
) b+ ~0 ?% j4 n9 A3 s) v. e
使用copy模块的deepcopy函数,递归拷贝对象中包含的子对象,源对象和拷贝对象所有的子对象也不相同。
7 {. @1 D4 u' P/ ]+ p" d" I8 u
1 B2 M, i4 E# m; g: q
# -*- coding: utf-8 -*-
/ p2 v, N& k. o; m) G& [3 [5 Z
# author : Flyme awei
" _( u% M. O! n! K' [
# 开发时间: 2022/7/1 15:32
) E' _& a1 X& e2 H4 [
' q( P4 f) U! M c+ Y/ D
import copy
5 S* `: E8 X" a8 ~, }' s+ W
- A/ q% w' f- N: q
2 e- `$ O8 J9 x
class CPU:
2 X$ F5 j' C1 F' j
pass
1 D5 [6 S. e V8 s; H2 O1 P. A
& B4 W# u- I$ n; i' ?# a& ~
" B L- o0 b8 N) w
class Disk:
. l% a+ R: J/ Z5 f
pass
Z8 v. `/ J2 v) L, x
* ~, b' E+ S ^. i+ f: m. {. Y
* E' E- B7 r. j+ W: F$ z
class Computer:
$ g/ [* ^8 @3 m5 f
def __init__(self, cpu, disk): # 给对象的实例属性进行初始化
/ }% {/ e& e( C, A2 I- Q
self.cpu = cpu
0 }& l5 i, {* H6 a* P* F
self.disk = disk
' I2 U2 F T; M5 R
" @" H" V, |& ]& L4 N
0 J% [% q4 a' o: H2 t
cpu = CPU() # 创建一个 CPU 对象
1 [; k( d9 A% @7 W9 t
disk = Disk() # 创建一个硬盘类对象
3 p/ B* C! U ]$ A
computer = Computer(cpu, disk) # 创建一个计算机类对象
- p/ B3 [2 H, K% g) x
; h+ f" A1 o4 B
# 深拷贝
1 {9 l- E4 {3 R( T6 O" z0 G. k
computer1 = copy.deepcopy(computer)
% {$ x. |5 d6 e5 X0 P
print(computer, computer.cpu, computer.disk)
0 g4 c- m2 N/ M& T; l
print(computer1, computer1.cpu, computer1.disk)
: S( W' e! o2 F6 X" L
" a w: a$ l* w% { L. e- @
# 类的深拷贝
% q# B- P' z3 ~, v; y% G
# 使用copy模块的deepcopy函数,递归拷贝对象中包含的子对象
2 g' b! G; m8 ^) q
# 源对象和拷贝对象所有的子对象也不同
5 r+ D; o9 n1 d7 t7 Z9 |( ~
1
* j j: U( R5 O9 j2 @2 @1 d
2
7 c2 @% M- i+ h1 I" ^/ J7 ]
3
6 W$ h) T) q1 ~: a' Q& o
4
" ^0 q7 K, f% [ i @
5
. }0 M5 Z: c/ ~8 F) A$ F0 T* j
6
" A) A6 B3 [% E3 Z$ m) T: Y
7
# \8 B4 D; w/ v/ \
8
) H9 K" N2 f0 Y( r7 a9 U1 \
9
' Q9 c+ ]% U6 ?) ]( b4 D2 n
10
4 Y3 b7 f9 }, z9 Y4 G& a# w5 I
11
8 E& D5 Q1 ? _% p
12
# V. ]& g+ M+ _8 Z+ w; w6 O
13
1 `( M; t3 d* p1 y: u' m7 X5 o# h
14
& q0 |* ?$ M% U% e) Y
15
; i2 g9 m1 E/ n( c' S' j
16
! c# h: n$ I" f0 |5 [
17
6 B! `* V9 X' u5 g0 m/ o% a
18
: n U8 Z5 @. n7 C; f' O
19
; P O# a1 j M
20
! I5 o2 R0 G- J+ n' Z
21
/ I3 y; n/ _1 w% ?9 L1 Q9 q
22
0 b$ Z+ a3 e1 f9 i& `, r
23
! Y. |* m3 F- i% K- }
24
+ k/ Y6 i2 q; Q3 f& p, X
25
9 p+ C+ k$ s# G- k+ g
26
. T" @# j1 U( C2 G4 [3 l
27
0 b* J9 K, j% ]- B- l2 }5 L
28
6 v, I8 Y9 y6 }! y7 I1 x
29
* D, h9 h0 d& b
30
7 l$ T9 g9 Z) B2 o7 v- j
31
0 A" Q8 s1 q% N: ]5 `/ `
32
$ X9 B% a5 Q( l
33
, @# [9 e- N7 [" k
/ B: i, G; W8 f: b5 A6 v4 u [7 W
4 d3 D' T. [9 c
深拷贝:创建一个新的对象,并且递归的复制它所包含的对象。
# N) V: P0 {* ~3 w
, [. [, n2 t" v w
修改其中一个,另外一个不会改变。因此,新对象和原对象没有任何关联。
5 @* I9 v4 _4 @$ N2 _& U
例如:{copy模块的deepcopy()函数}
, [/ D# c1 z# D% n6 v) d4 b1 ~; r
% R& X! k+ @+ ~3 U; R; E
七、总结
- D# \0 B! m: G3 u$ V$ m0 m' [
面向对象三大特征:
% a# C, U, k8 x& z3 Y p" L
' s0 M, k3 Z! z( M/ K/ C/ l
封装:将属性和方法包装到类对象中,在方法内部对属性进行操作,在类对象外部调用方法。
, S# g2 g3 S/ V; u' f* w
继承:多继承、方法重写
y) H, g, ]% W' f% L8 M$ N4 A4 q
多态:即便不知道一个变量所引用的对象是什么类型,仍然可以使用这个变量调用方法,在运行过程中根据变量所引用的对象类型,动态决定调用那个对象中的方法。
& c+ a4 u$ U+ T% e5 P: t
动态语言:关注对象的行为
7 w9 P, B$ q2 k0 ^( p1 z2 s
静态语言:继承、方法重写、父类引用指向子类对象
/ q+ K- o/ u ^# R5 l9 l
object类
- O# H8 {; l7 ?' t
+ d, S, o5 k$ C5 D% ~
所有类的父类
# A* W0 ] d0 r; @1 u Z
__new__()创建对象
& F. J4 r( G; R; V2 n
__init__()初始化对象
) \% v; H& v1 w$ E# g& N
__str__()返回对象的描述
8 b& d2 ~* @; S4 ?* i, M
————————————————
# ~5 j+ l, N* h, B
版权声明:本文为CSDN博主「北极的三哈」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
3 C# t2 V$ @4 [0 S) e- p
原文链接:https://blog.csdn.net/m0_68744965/article/details/126376382
( m4 v( h( \/ t
0 g# y' P0 x. o8 h/ X- Y$ R
1 W* c! E% P9 g" r4 d- I; p
欢迎光临 数学建模社区-数学中国 (http://www.madio.net/)
Powered by Discuz! X2.5