Python面向对象编程(二)——— 类与对象的成员与方法

一、类与对象的成员

1.1 类的成员

1.1.1 类的成员定义

成员是指对象特有的一些属性,如人的身高、性别、年龄、学历等等。属于类的成员是该类所有对象共享的,类成员属于类,可以通过类名或对象名访问。下面我们以一个Student类来解释一下:

class Student(object):
    age = 20

student1 = Student()
student2 = Student()

print(Student.age)
print(student1.age)
print(student2.age)

20
20
20

我们先定义了一个Student类,然后定义了一个类成员age,然后我们可以通过类名访问,也可以通过对象名访问。

1.1.2 修改和增加类成员

Python支持修改和动态增加类成员,我们看下面的例子:

class Student(object):
    age = 20

Student.age = 22
Student.height = 180

student1 = Student()
student2 = Student()

print(Student.age)
print(student1.age)
print(student2.age)

print(Student.height)
print(student1.height)
print(student2.height)

22
22
22
180
180
180

我们可以发现类成员的值修改了,而且增加了一个类成员

1.2 对象的成员

1.2.1 对象的成员的定义

属于对象的成员主要指在构造函数__init__()中定义的,定义和使用时必须以 self 作为前缀,self 相当于对象本身,传入参数时不需要传入self参数。同一个类的不同对象之间的成员互不影响,只能通过对象名访问,下面以Student类来创建实例:

class Student(object):
    def __init__(self,age,height):
        self.age = age
        self.height = height

student1 = Student(age = 20, height = 175)
student2 = Student(age = 25, height = 185)

print(student1.age)
print(student2.age)
print(student1.height)
print(student2.height)

20
25
175
185

由此可见,我们由Student类实例化的两个对象是不一样的。

1.2.2 修改和增加对象的成员

1、修改对象的成员,例子如下:

class Student(object):
    def __init__(self,age):
        self.age = age

student1 = Student(age = 20)
student2 = Student(age = 25)

print(student1.age)
print(student2.age)

student1.age = 28

print(student1.age)
print(student2.age)

20
25
28
25

我们发现当修改了student1的成员后,student2的成员并没有改变,这就说明同一个类的不同对象之间互不影响。

2、增加对象的成员,例子如下:

在这里插入图片描述我们可以发现打印出了student1的weight成员为100,而打印student2时则会报错,这也说明同一个类的不同对象是互不影响的。

1.3 私有成员与公有成员

定义类或者对象的成员时,如果成员名是以两个下划线(__)开头则表示是私有成员。私有成员在类的外部不能直接访问,一般是在类的内部进行访问和操作,或者在类外部通过调用对象的公有成员方法来访问。但可以通过"类名/对象名._类名_xxx"来访问私有成员,但是一般不要这样做,会破坏类的封装性。

1.3.1 私有成员

1.3.1.1 类的私有成员

访问类的私有成员有三种方式:
1、内部访问
2、通过方法访问(类方法、静态方法、实例方法)
3、通过"类名._类名__xxx"来访问

1、先看一下从内部访问:

class Student(object):
    __age = 20
    print(__age)
    __age = 25
    print(__age)

20
25

因为定义类会运行类内部的代码,上面代码实现了从内部访问和修改。

2、下面看一下通过方法访问:

class Student(object):
    __age = 20
    
    # 对象的实例方法
    def show1(self):
        return(Student.__age)
    
    # 类方法
    @classmethod
    def show2(cls):
        return(cls.__age)
    
    # 静态方法
    @staticmethod
    def show3():
        return(Student.__age)

# 用实例化对象访问
student = Student()
print(student.show1())
print(student.show2())
print(student.show3())

# 分隔
print()

# 调用类方法访问
print(Student.show2())

# 分隔
print()

# 调用静态方法访问
print(Student.show3())

20
20
20

20

20

关于方法的调用,下面会讲解,这里只说明访问类的私有成员,可以采用这种方法。

3、通过"类名/对象名._类名__xxx"来访问

class Student(object):
    __age = 20
    
print(Student._Student__age)

20
1.3.1.2 对象的私有成员

访问类的私有成员有三种方式:
1、内部访问
2、通过实例方法访问
3、通过"对象名._类名__xxx"来访问

1、从内部访问

class Student(object):
    def __init__(self,age = 20): # 构造函数
        self.__age = age
        print(self.__age)

student = Student()

20

2、通过实例方法访问

class Student(object):
    def __init__(self,age = 20): # 构造函数
        self.__age = age

    def show(self):	# 实例方法
        return(self.__age)
        

student = Student()
print(student.show())

20

3、通过"对象名._类名__xxx"来访问

class Student(object):
    def __init__(self,age = 20):
        self.__age = age

student = Student()
print(student._Student__age)

20

1.3.2 公有成员

公有成员是可以公开使用的,既可以在类的内部进行访问,也可以在外部程序中使用,看一下下面的例子:

class Student(object):
    age = 20 # 类成员
    print(age) # 访问类的成员
    def __init__(self,height=180):
        self.height =  height # 对象成员

# 分隔符号
print()

# 类访问类的成员
print(Student.age)

# 类的实例化
student = Student()

# 分隔符号
print()

# 对象访问类成员
print(student.age)
# 对象访问对象的成员
print(student.height)

20

20

20
180

我们可以看到既可以在类内部访问,又可以在外部直接访问。

1.3.3 特殊成员

Python中以以下划线开头和结尾的成员名有特殊的意义,属于特殊成员。
1、_ xxx:保护成员,只有类对象和子类对象可以访问这些成员
2、__ xxx __:系统定义的特殊成员
2、__xxx:类中的私有变量,一般只能类对象自己访问,子类对象也不能访问。

二、类与对象的方法

方法用来描述类与对象所具有的行为,例如字符串对象的拼接、删除,文件对象的打开和关闭等等。在Python中方法可以大致分为四大类:公有方法、私有方法、静态方法和类方法。公有方法和私有方法一般属于对象的实例方法,静态方法和类方法都可以通过类名和对象名调用。

2.1 类方法与静态方法

2.1.1 类方法

类方法需要用装饰器 @classmethod 来修饰,一般将 cls 作为类方法的第一个参数,表示类本身,在调用类方法时不需要为该参数传值,例子如下:

class Student(object):
    age = 20
    @classmethod
    def show(cls):
        return(cls.age)

# 通过类名调用类方法
print(Student.show())

# 通过对象名调用类方法
student = Student()
print(student.show())

20
20

我们可以通过类名或者对象名来调用类方法

2.1.2 静态方法

静态方法需要用装饰器 @staticmethod 来装饰,静态方法中则不需要绑定类,也相当于是一个函数,在后面我们说一下函数与方法的区别。我们以一个例子来看一下:

class Student(object):
    age = 20
    @staticmethod
    def show():
        return(Student.age)

# 通过类名调用静态方法
print(Student.show())

# 通过对象名调用静态方法
student = Student()
print(student.show())

20
20

我们可以用类名或者对象名来调用静态方法

2.2 公有方法与私有方法

2.2.1 公有方法

公有方法通过对象名直接访问,但不可以用类名访问

1、我们看一下对象名访问

class Student(object):
    def __init__(self,age): # 绑定实例属性
        self.age = age
        
    def show(self): # 公有方法
        return(self.age)

# 类的实例化
student = Student(20)
# 通过对象名调用公有方法
print(student.show())

20

2、下面我们看一下类名访问
在这里插入图片描述
直接访问会报错,我们可以采取另外一种方式

3、通过将对象作为一个参数传入,则可使用

class Student(object):
    def __init__(self,age=20): # 绑定实例属性
        self.age = age
        
    def show(self): # 公有方法
        return(self.age)

student = Student()
print(Student.show(student))

20

因为self参数相当于是对象本身,所以可以这样调用

2.2.2 私有方法

私有方法不能通过对象名直接调用,只能在实例方法中通过self调用或者在外部用Python支持的特殊方式使用

1、从内部访问,可以用self调用

class Student(object):
    def __init__(self,age=20): # 绑定实例属性
        self.age = age
        
    def __show(self): # 公有方法
        return(self.age)
    
    def fun(self):
        print(self.__show())
    
student = Student()
print(student.fun())

20

可以将方法绑定到对象上,然后在内部进行访问

2、从外部访问,可以通过_对象名__方法名访问

class Student(object):
    def __init__(self,age=20): # 绑定实例属性
        self.age = age
        
    def __show(self): # 公有方法
        return(self.age)
    
student = Student()
print(student._Student__show())

20

三、方法与函数的区别

在Python中,函数与方法是有区别的。方法一般指与类或对象绑定的函数,通过类或对象调用方法时,类或对象本身将被作为第一个参数传递过去,普通函数没有这个特点。

3.1 类中的函数与方法

3.1.1 类中的函数

在Python中,类方法中的静态方法实际就是函数,下面我们以一个例子来说明

class Student(object):
    pass

@staticmethod # 静态方法不与类绑定,相当于函数
def fun(age):
    Student.age = age

Student.fun = fun # 动态增加函数
print(Student.fun) # 查看类型
Student.fun(35) # 传入参数
print(Student.age) # 打印值

<function fun at 0x000001C64280B7B8>
35

我们可以看到它的类型是一个function,而不是绑定类的方法。

3.1.2 类中的方法

class Student(object):
    pass

@classmethod # 类方法与类绑定
def fun(cls,age):
    cls.age = age

Student.fun = fun # 动态增加方法
print(Student.fun) # 查看类型
Student.fun(35) # 传入参数
print(Student.age) # 打印值

<bound method fun of <class '__main__.Student'>>
35

我们查看它的类型,可以发现它是一个绑定在类上的方法,可以通过这种方法动态增加类的方法

3.2 对象中的函数与方法

3.2.1 对象中的函数

class Student(object):
    pass

def fun(self,age): # 定义一个函数
    self.age = age

student = Student() 
student.fun = fun  # 直接赋值的话,相当于是一个函数,这点与类不同
print(student.fun) # 打印类型
student.fun(student,45) # 传入参数时,必须传入对象名称,因为它是一个函数
print(student.age)

<function fun at 0x000001C6429B2048>
45

打印它的类型,我们可以发现它是一个函数,调用时必须要把对象作为第一个参数传入。

3.2.2 对象中的方法

动态给对象绑定方法需要用到 types库,调用types.MethodType(方法名,对象名)来绑定

import types

class Student(object):
    pass

def fun(self,age): # 定义一个函数
    self.age = age

student = Student() 
student.fun = types.MethodType(fun,student) # 第一参数为需要绑定的方法,第二个参数为对象名称
print(student.fun) # 打印类型
student.fun(45) # 传入参数时,不需要传入对象名称,因为它是一个方法
print(student.age)

<bound method fun of <__main__.Student object at 0x000001C642F2EB70>>
45

我们可以看到它的类型是一个绑定方法,调用时不需要传入对象名。

发布了38 篇原创文章 · 获赞 45 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/a1786742005/article/details/89048814