Python中Class(类)的超详细说明!
Python中Class(类)的超详细说明!
Class 类
用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
一个人(身高:一米八)要吃饭、喝水、睡觉;
一只老虎(体重:300斤)要奔跑、洗澡、捕猎。
一、名词定义
- 类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
- 方法: 类中定义的 函数 。
- 类变量: 类变量在整个实例化的对象中是公用的。
- 一般位置 :类变量定义在类中且在函数体之外。
- 固有属性由类变量表示。
- 类变量通常不作为实例变量使用。
- 对类变量的修改会影响到类的所有实例。
- 数据成员: 类变量或者实例变量用于处理类及其实例对象的相关的数据。
- 方法重写: 如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
- 实例变量:
- 一般位置 :在类的
__init__
声明中。 - 属性 是用变量来表示的,这种变量就称为实例变量,且一般是自定义属性。
- 一般位置 :在类的
- 局部变量:
- 一般位置 :定义在方法中的变量。
- 只作用于当前实例(对象)的类。
- 一旦函数或方法执行完毕,局部变量就会被销毁。
- 局部变量与类本身无关,无论是在类的内部还是外部定义的方法中,都可以有局部变量。
- 继承: 即一个派生类(derived class)继承基类(base class)的属性和方法。继承也允许把一个派生类的对象作为一个基类对象对待。
- 实例化: 创建一个类的实例,即创建一个类的具体对象。
- 实例是可以更改、删除原属性的。
- 对象: 通过类定义的数据结构实例,实例即对象。对象包括两个数据成员(类变量和实例变量)和方法。
二、先睹为快
通俗举例:
1
2
3
4
5
6
7
|
#通俗举例: 定义一个人(男性)要吃饭、喝水、睡觉; 现在有个具体的人,他被赋予上述定义,所以他便是男人,会吃饭,会喝水,会睡觉。 #类名:一个人 #属性:男性 #方法:吃饭、喝水、睡觉 #对象:这个具体的人(赋予这个人相同的属性、方法的过程叫“实例化”) |
- 无
__init__
代码举例(有__init__
的后面会写):1234567891011121314151617181920class
Calculator:
# Calculator:类名
name
=
'Good calculator'
# name:类变量(固有属性)
price
=
18
# price:类变量(固有属性)
def
add(
self
,x, y):
# add():方法
result
=
x
+
y
# result:局部变量
print
(result)
def
minus(
self
, x, y):
# minus():方法
result
=
x
-
y
# result:局部变量
print
(result)
def
times(
self
, x, y):
# times():方法
print
(x
*
y)
def
divide(
self
, x, y):
# divide():方法
print
(x
/
y)
cal1
=
Calculator()
# ☆实例化(cal1也有了相同的属性和方法)
————————————————————————————————————————————————————————————————————————————————————————————
>>> cal1.name
-
-
-
-
-
>
'Good calculator'
>>> cal1.add(
1
,
2
)
-
-
-
-
-
>
3
>>> cal1.price
-
-
-
-
-
>
18
>>> cal1.price
=
25
>>> cal1.price
-
-
-
-
-
>
25
# 实例的属性可以修改
三、详细解释
(1)self
- 在用 def 定义方法时,第一个参数一定得是 self 。
- self 代表的是类的实例(对象),本质是代表当前对象的地址,不是类;而 self.class 则指向类。请看 VCR :
1234567891011
class
Test:
def
prt(
self
):
print
(
self
)
print
(
self
.__class__)
t
=
Test()
t.prt()
————————————————————————————————————————————————————————————————————————————————————————————
#输出结果为(两个 print 的结果):
<__main__.Test instance at
0x100771878
>
__main__.Test
- self 不是 python 关键字,可以把它换成别的单词,但仍强烈建议使用 self。
(2)方法
- 在类的内部,使用 def 关键字来定义一个方法。
- 与一般函数不同,类的方法在定义时必须包含参数 self,且为第一个参数,self 代表的是类的实例。
- self 不是 python 的关键字,所以可以用别的单词来代替 self 。
但按照惯例,最好就用 self 。
1
2
|
def add( self ,x,y) # add即为方法名,x和y为调用该函数需要输入的参数 result = x + y |
__init__
一种内置的方法,可称之为“构造方法”,初始化(Initialize的缩写)
前后各两个下划线
在实例化时,会自动调用,用来初始化自定义属性
- 有
__init__
代码举例(没给出默认自定义属性,实例化时需要手动给出):下方代码要注意一点,自定义属性是 hight 这些,不是 hig 这些,hig 只是输入参数。1234567891011121314151617181920212223242526272829class
Calculator:
# Calculator:类名
class_variable
=
"I am a class variable"
# 这是一个类变量(固有属性)
name
=
'Good calculator'
# name:类变量(固有属性)
price
=
18
# price:类变量(固有属性)
#*****************************
def
__init__ (
self
, hig, wid, wei):
# *
self
.hight
=
hig
# hight:实例变量(自定义属性) *
self
.width
=
wid
# width:实例变量(自定义属性) *
self
.weight
=
wei
# weight:实例变量(自定义属性) *
#*****************************
def
add(
self
,x, y):
# add():方法
result
=
x
+
y
# result:局部变量
print
(result)
def
minus(
self
, x, y):
# minus():方法
result
=
x
-
y
# result:局部变量
print
(result)
def
times(
self
, x, y):
# times():方法
print
(x
*
y)
def
divide(
self
, x, y):
# divide():方法
print
(x
/
y)
————————————————————————————————————————————————————————————————————————————————————————————
#先运行程序
>>> cal2
=
Calculator(
1
,
5
,
12
)
#实例化时,一定要给出自定义属性的内容
>>> cal2.name
-
-
-
-
-
>
'Good calculator'
>>> cal2.hight
-
-
-
-
-
>
1
>>> cal2.add(
1
,
2
)
-
-
-
-
-
>
3
>>> cal2.price
-
-
-
-
-
>
18
>>> cal2.price
=
25
>>> cal2.price
-
-
-
-
-
>
25
# 实例的固有、自定义属性都可修改
- 有
__init__
代码举例(给出默认自定义属性):1234567891011...
#同上
#*******************
def
__init__ (
self
, hight
=
1
, width
=
5
, weight
=
12
):
*
self
.hight
=
hight
# hight:自定义属性 *
self
.width
=
width
# width:自定义属性 *
self
.weight
=
weight
# weight:自定义属性 *
#*******************
...
#同上
————————————————————————————————————————————————————————————————————————————————————————————
#先运行程序
>>> cal2
=
Calculator()
#实例化时,不用再给出自定义属性,除非要修改
super().__init__()
的功能与用法
在Python中,super() 函数是用于调用父类(超类)的一个方法。在类的构造函数(
__init__
)中使用super().__init__()
是一种常见的做法(特别是在多重继承的情况下,它确保了父类被正确地初始化,但是这里不过多介绍多重继承)。
————
python3 的 super() 函数就是此格式,比 python2 的 super() 函数要精简。- 用法:假设我们有一个基类(父类)和一个派生类(子类),子类在初始化时,可能需要父类的一些已经设置好的属性或方法,我们希望在子类初始化时也初始化基类。这时就可以使用
super().__init__()
。 - 示例:
1234567891011121314151617
class
Parent:
def
__init__(
self
, name):
self
.name
=
name
print
(f
"Parent with name: {self.name}"
)
class
Child(Parent):
def
__init__(
self
, name, age):
super
().__init__(name)
# 调用父类的__init__方法
self
.age
=
age
print
(f
"Child with name: {self.name} and age: {self.age}"
)
# 使用子类
child_instance
=
Child(
"Alice"
,
10
)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# 运行结果
Parent with name: Alice
Child with name: Alice
and
age:
10
这里用到了
f-string
字符,感兴趣的可以上网搜搜,或者直接问 GPT 。
- 用法:假设我们有一个基类(父类)和一个派生类(子类),子类在初始化时,可能需要父类的一些已经设置好的属性或方法,我们希望在子类初始化时也初始化基类。这时就可以使用
__call__
一种内置的方法,前后各两个下划线。
这个内置方法,有点多此一举的感觉,不过有些妙用,需要慢慢体会…
该内置函数的作用是:
“实例可以直接当函数用,且其效果就是 __call__
函数的效果”,此时, __call__
函数的输入参数,就是实例的输入参数。
具体使用代码见下方运行程序结果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
class Calculator: # Calculator:类名 class_variable = "I am a class variable" # 这是一个类变量(固有属性) name = 'Good calculator' # name:类变量(固有属性) price = 18 # price:类变量(固有属性) #***************************** def __init__ ( self , hig, wid, wei): # * self .hight = hig # hight:实例变量(自定义属性) * self .width = wid # width:实例变量(自定义属性) * self .weight = wei # weight:实例变量(自定义属性) * #***************************** def __call__ ( self , test_value): print ( "Output is:" + str (test_value)) def add( self ,x, y): # add():方法 result = x + y # result:局部变量 print (result) ———————————————————————————————————————————————————————————————————————————————————————————— #先运行程序 >>> cal2 = Calculator( 1 , 5 , 12 ) #实例化时,一定要给出自定义属性的内容 >>> cal2.name - - - - - > 'Good calculator' >>> cal2( 111 ) - - - - - > Output is : 111 |
多加一嘴:其余自命名方法(函数)的调用方式为 实例名.方法名()
。
(3)继承
就是先定义了一个 基准类,后面想再定义一个 派生类,该派生类想沿用基准类的属性和方法,这种沿用过程就叫“继承”。
子类(派生类 DerivedClassName)会继承父类(基类 BaseClassName)的属性和方法。
- 单继承:
- 当基类和派生类 处于同一个模块中 时:
1234
class
派生类名(基类名):
...
代码块
...
- 当基类和派生类不在同一个模块中时,需要从基类所在模块导入基类:
- 写法一(仅导入基类):
1234567
#假设基类 BaseClassName 在模块 modname 中
from
modname
import
BaseClassName
class
DerivedClassName(BaseClassName):
...
代码块
...
- 写法二(直接导入基类所在模块):
1234567
#假设基类 BaseClassName 在模块 modname 中
import
modname
class
DerivedClassName(modname.BaseClassName):
...
代码块
...
- 写法一(仅导入基类):
示例:
12345678910111213141516171819202122232425262728293031#类定义
class
people:
#定义基本属性
name
=
''
age
=
0
#定义私有属性,私有属性在类外部无法直接进行访问
__weight
=
0
#定义构造方法
def
__init__(
self
,n,a,w):
self
.name
=
n
self
.age
=
a
self
.__weight
=
w
def
speak(
self
):
print
(
"%s 说: 我 %d 岁。"
%
(
self
.name,
self
.age))
#单继承示例
class
student(people):
grade
=
''
def
__init__(
self
,n,a,w,g):
#调用父类的构函
people.__init__(
self
,n,a,w)
self
.grade
=
g
#覆写父类的方法
def
speak(
self
):
print
(
"%s 说: 我 %d 岁了,我在读 %d 年级"
%
(
self
.name,
self
.age,
self
.grade))
s
=
student(
'ken'
,
10
,
60
,
3
)
s.speak()
————————————————————————————————————————————————————————————————————————————————————————————
#输出结果为:
ken 说: 我
10
岁了,我在读
3
年级
- 当基类和派生类 处于同一个模块中 时:
- 多继承:
12
#参考菜鸟教程,基本不用:
https:
/
/
www.runoob.com
/
python3
/
python3
-
class
.html
(4)方法重写
如果父类定义的方法的功能不能满足需求,则可以在子类重写父类的方法。
示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
class Parent: # 定义父类 def myMethod( self ): print ( '调用父类方法' ) class Child(Parent): # 定义子类 def myMethod( self ): print ( '调用子类方法' ) c = Child() # 子类实例 c.myMethod() # 子类调用重写方法 super (Child,c).myMethod() #用子类对象调用父类已被覆盖的方法 ———————————————————————————————————————————————————————————————————————————————————————————— #输出结果为: 调用子类方法 调用父类方法 |
四、实例变量、局部变量、类变量的 GPT 解释
在Python的继承机制中,理解实例变量、局部变量、和类变量是非常重要的。这些变量在类及其对象中的作用域和生命周期各不相同。下面是对这些变量的详细解释:
- 实例变量(Instance Variables)实例变量也称为对象变量,它们是在类的实例(即对象)中定义的变量。每个实例都有自己独立的实例变量副本,即使两个实例属于同一个类,它们的实例变量值也可以是不同的。实例变量通常通过类的构造方法(
__init__
)来初始化。123456789class
MyClass:
def
__init__(
self
, value):
self
.instance_variable
=
value
# 这是一个实例变量
obj1
=
MyClass(
10
)
obj2
=
MyClass(
20
)
print
(obj1.instance_variable)
# 输出: 10
print
(obj2.instance_variable)
# 输出: 20
- 局部变量(Local Variables)局部变量是在函数或方法内部定义的变量。它们的作用域仅限于定义它们的函数或方法。一旦函数或方法执行完毕,局部变量就会被销毁。局部变量与类本身无关,无论是在类的内部还是外部定义的方法中,都可以有局部变量。
12345678
class
MyClass:
def
my_method(
self
):
local_variable
=
"I am a local variable"
# 这是一个局部变量
print
(local_variable)
obj
=
MyClass()
obj.my_method()
# 输出: I am a local variable
# 在这里,local_variable 已经不存在了
- 类变量(Class Variables)类变量是在类级别定义的变量,它们不属于类的任何特定实例。相反,它们被类的所有实例共享。类变量可以通过类本身来访问,也可以通过类的任何实例来访问。当通过实例修改类变量时,这个改变会影响到所有实例,因为所有的实例共享同一个类变量。
123456789101112131415161718
class
MyClass:
class_variable
=
"I am a class variable"
# 这是一个类变量
def
__init__(
self
, value):
self
.instance_variable
=
value
def
print_variables(
self
):
print
(
self
.class_variable)
# 通过实例访问类变量
print
(MyClass.class_variable)
# 直接通过类名访问类变量
# 修改类变量
MyClass.class_variable
=
"I have been modified"
obj1
=
MyClass(
10
)
obj2
=
MyClass(
20
)
obj1.print_variables()
# 输出: I have been modified 和 I have been modified
obj2.print_variables()
# 输出同上,因为类变量被所有实例共享
注意:尽管可以通过实例访问类变量,但最好通过类名来访问和修改类变量,以避免潜在的混淆。特别是在通过实例修改类变量时,要清楚这样做会影响所有实例共享的类变量值。
总结
到此这篇关于python中Class(类)的文章就介绍到这了。
学习资料见知识星球。
以上就是今天要分享的技巧,你学会了吗?若有什么问题,欢迎在下方留言。
快来试试吧,小琥 my21ke007。获取 1000个免费 Excel模板福利!
更多技巧, www.excelbook.cn
欢迎 加入 零售创新 知识星球,知识星球主要以数据分析、报告分享、数据工具讨论为主;
1、价值上万元的专业的PPT报告模板。
2、专业案例分析和解读笔记。
3、实用的Excel、Word、PPT技巧。
4、VIP讨论群,共享资源。
5、优惠的会员商品。
6、一次付费只需99元,即可下载本站文章涉及的文件和软件。
共有 0 条评论