Python 面向对象程序设计

Python 面向对象程序设计

image

1 面向过程编程

面向过程——Procedure Oriented,是一种以过程为中心的编程思想,它首先分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,在使用时依次调用,是一种基础的顺序的思维方式。面向过程开发方式是对计算机底层结构的一层抽象,它将程序分为数据和操纵数据的操作两部分,其核心问题是数据结构和算法的开发和优化。

最典型的就是流水线,上一道工序完成后,后面的流程才能进行。

  • 面过程编程的特点:

    功能模块化,代码流程化

  • 优点:

    性能高,适合资源紧张、实时性强的场合

  • 缺点:

    不易复用和不易扩展

2 面向对象编程

面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想。OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。

面向对象的程序设计把计算机程序视为一组对象的集合,而每个对象都可以接收其他对象发过来的消息,并处理这些消息,计算机程序的执行就是一系列消息在各个对象之间传递。

在Python中,所有数据类型都可以视为对象,当然也可以自定义对象。自定义的对象数据类型就是面向对象中的类(Class)的概念。

3. 面向过程和面向对象的优缺点

面向对象 面向过程
特性 抽象、继承、封装、多态 功能模块化,代码流程化
优点 易维护、易复用、易扩展、低耦合 性能高,适合资源紧张、实时性强的场合
缺点 性能比面向过程低 没有面向对象易维护、易复用、易扩展

4. 由浅入深了解面向对象

4.1 学生选课为例

"""
1, 要定义学生的信息: 姓名,性别,年龄,学校,所选课程
"""
# 学生的特征:
student_name = 'Hans'
student_gender = 'M'
student_age = 20
shool = '社会大学'
student_course = []

# 学生的功能:选课
def course_selection_system(name, gender, age, shool, course):
    student_course.append(course)
    print("学生:%s 性别:%s 年龄:%s 在%s 期间所选课程:%s" % (name, gender, age, shool, student_course))
# 执行结果:
course_selection_system(student_name, student_gender, student_age, shool, "如何接受社会的毒打")
学生:Hans 性别:M 年龄:20 在社会大学 期间所选课程:['如何接受社会的毒打']


"""
2, 把学生的信息定义成一个字典
"""
student1 = {
    'student_name': 'Hans',
    'student_gender': 'M',
    'student_age': 20,
    'shool':'社会大学',
    'student_course':[]
}

def course_selection_system(student, course):
    student1['student_course'].append(course)
    print("学生:%s 性别:%s 年龄:%s 在%s 期间所选课程:%s" % (student['student_name'], student['student_gender'], \
                                               student['student_age'], student['shool'], student['student_course']))
#执行结果:
course_selection_system(student1, "如何接受社会的毒打")
学生:Hans 性别:M 年龄:20 在社会大学 期间所选课程:['如何接受社会的毒打']

"""
3, 把选课的函数放到字典里, 某个学生要选课成功,里面要包括他的特征和技能,
这样一个学生他的特征和功能都有了
"""

def course_selection_system(student, course):
    student1['student_course'].append(course)
    print("学生:%s 性别:%s 年龄:%s 在%s 期间所选课程:%s" % (student['student_name'], student['student_gender'], \
                                               student['student_age'], student['shool'], student['student_course']))

student1 = {
    'student_name': 'Hans',
    'student_gender': 'M',
    'student_age': 20,
    'shool':'社会大学',
    'student_course':[],
    'course_select':course_selection_system
}

student2 = {
    'student_name': 'Jack',
    'student_gender': 'M',
    'student_age': 20,
    'shool':'社会大学',
    'student_course':[],
    'course_select':course_selection_system
}
student1['course_select'](student1, "五块钱如何花一星期")
student2['course_select'](student2, "如何接受社会的毒打")
#执行结果:
学生:Hans 性别:M 年龄:20 在社会大学 期间所选课程:['五块钱如何花一星期']
学生:Jack 性别:M 年龄:20 在社会大学 期间所选课程:['如何接受社会的毒打'
                
# 这是一两个学生,如果是十个,百个或更多都要手写一遍???
# 这时就需要面向对象了。
"""
对象是什么
	1. 程序中:
        	函数:盛放数据的容器
            对象:盛放数据和函数的容器
	2. 现实生活中:
        	一切皆对象
            对象:特征与技能的结合体
"""

4.2 类和对象

"""
对象: 特征与技能的结合体
类:一系列对象相似的特征与相似的技能的结合体

站在不同的分类,划分的分类不一定一样

在程序中先有类再有对象。现实中先有对象,再有类
"""
# 把上面的程序 相同的部分拿出来,
student1 = {
    'student_name': 'Hans',
    'student_gender': 'M',
    'student_age': 20,
    'shool':'社会大学',
    'student_course':[],
    'course_select':course_selection_system
}

student2 = {
    'student_name': 'Jack',
    'student_gender': 'M',
    'student_age': 20,
    'shool':'社会大学',
    'student_course':[],
    'course_select':course_selection_system
}
"""
这个程序中有哪些是相同的:
学校(shool)和选课功能(course_selection_system)
可以把这两个功能提取出来
"""

student_public = {
    'shool':'社会大学',
    'course_select':course_selection_system
}
# 这个提取出来的公共的功能就是类,但在python中写有专业的写法:
class 类名():
    pass

# class为关键字 
# 类名一般首字母大写
# 代码:
class student_public():
    shool =  '社会大学'

    def course_selection_system(student, course):
        student1['student_course'].append(course)
        print("学生:%s 性别:%s 年龄:%s 在%s 期间所选课程:%s" % (student['student_name'], student['student_gender'], \
                                                   student['student_age'], student['shool'], student['student_course']))

# 类在定义的时候会执行,这是与函数不同的地方(函数在定义时不会执行,只有在调用时执行)
# 查看类的名称空间:
print(student_public.__dict__)
{'__module__': '__main__', 'shool': '社会大学', 'course_selection_system': <function student_public.course_selection_system at 0x000002ADBB6AA5F0>, '__dict__': <attribute '__dict__' of 'student_public' objects>, '__weakref__': <attribute '__weakref__' of 'student_public' objects>, '__doc__': None}

# 类的底层为字典
"""
类在定义时做了哪些:
	1. 类在定义时会立即执行
	2. 产生一个类的名称空间,然后把类体里执行的数据都放到名称空间里(__dict__返回的字典里)
	3. 把类的名称空间绑定给__dict__
	
变量放到类里面叫属性
函数放到类里面叫方法
"""

# 调用类
stu = student_public()
# 调用类从而产生对象。
# 调用类从而产生对象的过程,叫类的初始化

#查看对象的名称空间
print(stu.__dict__)
# 执行结果:
{}  # 一个空字典

# 现在用Python的语法把类定义出来了。
# 但是学生自己独有的特征还没有(自己的名字,自己的年龄等等),刚才看到了为空
# 给对象添加自己独有的特征
stu.__dict__['name'] = 'Hans'
stu.__dict__['gender'] = 'M'
stu.__dict__['age'] = 20
stu.__dict__['course'] = ['五块钱如何花一星期','如何接受社会毒打']

print(stu.__dict__)
# 执行结果:
{'name': 'Hans', 'gender': 'M', 'age': 20, 'course': ['五块钱如何花一星期', '如何接受社会毒打']}
# 对象的名称空间为一个空字典,现在添加了一些key,所以也可以对它进行取值
print(stu.__dict__['name'])
Hans

#在Python中一般不使用这种方法赋值和取值,Python中的方法
# 添加
stu.name = 'Hans'
stu.gender = 'M'
stu.age = 20
stu.course = ['五块钱如何花一星期','如何接受社会毒打']
# 取值
print(stu.__dict__)
print(stu.name)
# 执行结果:
{'name': 'Hans', 'gender': 'M', 'age': 20, 'course': ['五块钱如何花一星期', '如何接受社会毒打']}
Hans
# 这种方法只能在对象种使用


# 上面的方法依然是很个学生对象都要写一遍,所以这个方法也可以做成函数形式。
# 1. 定义一个类
class student_public():
    shool =  '社会大学'

    def course_selection_system(student, course):
        student['student_course'].append(course)
        print("学生:%s 性别:%s 年龄:%s 在%s 期间所选课程:%s" % (student['student_name'], student['student_gender'], \
                                                   student['student_age'], student['shool'], student['student_course']))
#
# 实例化对象
stu1 = student_public()
# 定义函数
def init(name,gender,age,course):
    stu1.name = name
    stu1.gender = gender
    stu1.age = age
    stu1.course = course


init('hans', 'M',20,['五块钱如何花一星期','如何接受社会毒打'])
print(stu1.__dict__)
# 执行结果:
{'name': 'hans', 'gender': 'M', 'age': 20, 'course': ['五块钱如何花一星期', '如何接受社会毒打']}

# init()函数中stu1为固定值,如果初始化一个学生,这个函数就不满足了,所以stu1的位置也要传参获得
def init(student,name,gender,age,course):
    student.name = name
    student.gender = gender
    student.age = age
    student.course = course

stu1 = student_public()
stu2 = student_public()

init(stu1,'hans', 'M',20,['五块钱如何花一星期','如何接受社会毒打'])
init(stu2,'jack', 'M',18,['五块钱如何花一星期','如何接受社会毒打'])
print(stu1.__dict__)
print(stu2.__dict__)
# 执行结果:
{'name': 'hans', 'gender': 'M', 'age': 20, 'course': ['五块钱如何花一星期', '如何接受社会毒打']}
{'name': 'jack', 'gender': 'M', 'age': 18, 'course': ['五块钱如何花一星期', '如何接受社会毒打']}
# 这样比较相对比较完美了,但是每次都要手动调用init()这个方法,有没有什么方法可以自动执行init()
# 可以把它写入到类里面,不过要变形
class student_public():
    def __init__(student, name, gender, age, course):
        student.name = name
        student.gender = gender
        student.age = age
        student.course = course

    shool = '社会大学'

    def course_selection_system(student, course):
        student['student_course'].append(course)
        print("学生:%s 性别:%s 年龄:%s 在%s 期间所选课程:%s" % (student['student_name'], student['student_gender'], \
                                                   student['student_age'], student['shool'], student['student_course']))

print(student_public.__dict__)
stu1 = student_public()
# 执行结果:
TypeError: student_public.__init__() missing 4 required positional arguments: 'name', 'gender', 'age', and 'course'
# 提示要四个参数,现在给它传四个参数:
stu1 = student_public('hans', 'M',20,['五块钱如何花一星期','如何接受社会毒打'])
print(stu1.__dict__)
# 现在执行不会报错
{'name': 'hans', 'gender': 'M', 'age': 20, 'course': ['五块钱如何花一星期', '如何接受社会毒打']}

#  __init__()上面写了五个参数,但是对象在调用的时候只让写四个,因为使用对象调用它会把自己当成第一个参数传递给函数。
# 在类中的方法,类和对象都可以调用,但是类在调用的时候,里面写了几个参数就要传几个参数,但是使用对象时它把自己当成第一个参数传过去,所以推荐使用对象调用

# Python中,因为方法中第一个参数为自己,所以把这个写成self
class student_public():
    def __init__(self, name, gender, age, course):
        self.name = name
        self.gender = gender
        self.age = age
        self.course = course

    shool = '社会大学'

    def course_selection_system(self, course):
        self['student_course'].append(course)
        print("学生:%s 性别:%s 年龄:%s 在%s 期间所选课程:%s" % (self['student_name'], self['student_gender'], \
                                                   self['student_age'], self['shool'], self['student_course']))

# 执行:
stu1 = student_public('hans', 'M', 20, '五块钱如何花一星期')   # 实例化对象
print(stu1.__dict__)
{'name': 'hans', 'gender': 'M', 'age': 20, 'course': '五块钱如何花一星期'}

# 判断一个
print(isinstance(stu1, student_public))
True

"""
调用类:
	1. 调用类(stu1 = student_public())会得到一个空对象,把这个空对象传给student_public.__dict__
	2. 调用student_public.__dict__(空对象,'hans', 'M',20,'五块钱如何花一星期')
	3. 得到一个初始化结果
	4. 在__init__里不能使用return 返回值,如果真要使用也只能返回None
"""

4.3 属性的查找顺序

类属性(在类中定义的):

# 1, 查看类属性
class student_public():
    def __init__(student, name, gender, age, course):
        student.name = name
        student.gender = gender
        student.age = age
        student.course = course

    shool = '社会大学'
stu1 = student_public('hans', 'M',20,'五块钱如何花一星期')
print(stu1.shool)

# 2, 增加一个类属性
stu1.country = 'CN'
print(stu1.__dict__)
{'name': 'hans', 'gender': 'M', 'age': 20, 'course': '五块钱如何花一星期', 'country': 'CN'}

# 3, 修改类属性
stu1.shool = '清华大学'
print(stu1.shool)
清华大学

# 4, 修改类属性
del stu1.shool

对象属性

class student_public():
    def __init__(student, name, gender, age, course):
        student.name = name
        student.gender = gender
        student.age = age
        student.course = course

    shool = '社会大学'
stu1 = student_public('hans', 'M',20,'五块钱如何花一星期')

# 1, 查看
print(stu1.name)
print(stu1.gender)
print(stu1.age)
hans
M
20

# 2, 修改
stu1.age = 18
print(stu1.age)
18

# 3,增加
stu1.result = '优'
print(stu1.__dict__)
{'name': 'hans', 'gender': 'M', 'age': 18, 'course': '五块钱如何花一星期', 'country': 'CN', 'result': '优'}

# 4, 删除
del stu1.result
print(stu1.__dict__)
{'name': 'hans', 'gender': 'M', 'age': 18, 'course': '五块钱如何花一星期', 'country': 'CN'}

属性查找顺序

1. 先在对象中查找,如果对象中没有则去类中查找
class student_public():
    def __init__(self, name, gender, age, course):
        self.name = name
        self.gender = gender
        self.age = age
        self.course = course

    shool = '社会大学'
    
print(stu1.shool)  # 这个shool为类中定义的
社会大学
print(stu1.__dict__['shool']) # 这个会报错,因为在对象stu1中根本没有shool这个属性,shool这个是类的属性,直接这么取是拿不到的,因为指定从对象stu1中的名称空间中取,对象stu1中的名称空间中根本没有。
#所以使用点(.)的方式,如果对象中的名称空间中没有,它会去类的名称空间中找。

class student_public():
    def __init__(self, name, gender, age, course):
        self.name = name
        self.gender = gender
        self.age = age
        self.shool = "清华大学"
        self.course = course

    shool = '社会大学'
    
print(stu1.shool)  # 这个shool为对象中定义的
清华大学



5. 面向对象绑定方法

5.1 小案例:计算一共产生了多少个对象

class Count():
    count = 0

    def __init__(self, name):
        self.name = name
        Count.count +=1  # 统计次数

s1 = Count('Hello')
s2 = Count('World')
print(Count.count)
# 执行结果:
2

# 类属性修改,所有对象都改。

# 还有一种写法:
class Count():
    count = 0

    def __init__(self, name):
        self.name = name
        self.__class__.count +=1	# 统计次数 和Count.count +=1 一样

s1 = Count('Hello')
s2 = Count('World')
print(Count.count)

5.2 绑定方法

绑定方法有两种:

  • 绑定给对象

    class Students():
        def __init__(self,name, age, gender):
            self.name = name
            self.age = age
            self.gender = gender
    
        def printInfo(self):
            print("%s %s %s" % (self.name, self.age, self.gender))
    
    stu = Students("Hans", 18, 'M')
    stu.printInfo()
    
    # 把printInfo方法绑定给对象stu
    
  • 绑定给类

    IP = '192.168.1.123'
    PORT = 3306
    
    class Mysql():
        def __init__(self, ip, port):
            self.ip = ip
            self.port = port
    
    mysql = Mysql(IP, PORT)
    print(mysql.ip,mysql.port)
    # 执行结果:
    192.168.1.123 3306
    
    # 如果有多个需要写多次。能不能把Mysql(IP, PORT)这个只写一次
    # 可以把这个放到一个函数里
    
    IP = '192.168.1.123'
    PORT = 3306
    
    class Mysql():
        def __init__(self, ip, port):
            self.ip = ip
            self.port = port
    
        def tell(self):
            mysql = Mysql(IP, PORT)
            return mysql
    
    obj  = Mysql(IP, PORT)
    obj1 = obj.tell()
    print(obj1.ip,obj1.port)
    
    # 写到函数里后,又有一个问题,mysql = Mysql(IP, PORT)现在是写的MySQL的,如果换别的数据库如redis,pg等是不是就不那么灵活了。
    
    class Database():
        def __init__(self, ip, port):
            self.ip = ip
            self.port = port
    
        @classmethod
        def tell(cls):
            obj = cls(IP, PORT)
            return obj
    
    
    mysql  = Database.tell()
    print(mysql.ip, mysql.port)
    # 换个IP和端口
    IP = '192.168.1.111'
    PORT = 6379
    redis  = Database.tell()
    print(redis.ip, redis.port)
    # 执行结果:
    192.168.1.123 3306
    192.168.1.111 6379
    
    
    # @classmethod 这个装饰器绑定给了类,以后类来调用,会自动把类名当成第一个参数传过来(cls)
    # 这时调用的时候,使用类名调用
    # 如果即用到绑定对象,又用到绑定类,推荐使用绑定对象,因为在对象中可以使用__class__拿到类
    

5.3 静态方法(非绑定方法)

import random
class Students():
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def randnum(self):
        print(random.randint(1, 10))

info = Students("Hans", 18)
info.randnum()
info.randnum()
# 执行结果:
1
4

# 在 def randnum(self) 中根本没有用到self,是不是可以不传?
# 现在在类中如果不传就会报错(TypeError: Students.randnum() takes 0 positional arguments but 1 was given),所以可以使用 @staticmethod

import random
class Students():
    def __init__(self,name,age):
        self.name = name
        self.age = age
    @staticmethod
    def randnum():
        print(random.randint(1, 10))

info = Students("Hans", 18)
info.randnum()
info.randnum()
# 执行结果:
4
9

6. 隐藏属性

为什么要隐藏属性?

有些时间有些数据,只想让内部看到,不想让外部看到。

如何隐藏属性

class Students():
    shool = '社会大学'
    def __init__(self,name,age):
        self.name = name
        self.age = age

stu1 = Students("Hans", 18)
print(stu1.shool)  
#shool是可以拿到的,如何把shool属性隐藏掉

class Students():
    __shool = '社会大学'   # 只需要在属性前面加两个下划线(__),只在前面加
    def __init__(self,name,age):
        self.name = name
        self.age = age

stu1 = Students("Hans", 18)
print(stu1.shool)
# 执行结果:
AttributeError: 'Students' object has no attribute 'shool'
    
print(stu1.__shool)
# 执行结果:
AttributeError: 'Students' object has no attribute '__shool'
# 就会发现shool这个不管用什么方法都访问不到了。
# 可以看一下它变成了什么?
print(Students.__dict__)
{'__module__': '__main__', '_Students__shool': '社会大学', '__init__': <function Students.__init__ at 0x000001E5EC31A0E0>, '__dict__': <attribute '__dict__' of 'Students' objects>, '__weakref__': <attribute '__weakref__' of 'Students' objects>, '__doc__': None}
# 可以看到shool前面加了双下划线(__)后就变成: _Students__shool(_类名__属性名)

# 现在在外面拿不到了,在内部是否可以拿到?
class Students():
    __shool = '社会大学'
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def get_shool(self):
        return self.__shool

stu1 = Students("Hans", 18)
print(stu1.get_shool())
# 执行结果:
社会大学
# 可以看到在内部可以拿到

# 其实如果外部要拿也能拿到:
stu1 = Students("Hans", 18)
print(stu1._Students__shool)  # 因为在类的名称空间为_Students__shool,所以直接取这个就可以拿到
print(Students._Students__shool)
# 不但可以隐藏类中的属性也可以隐藏方法和对象中的属性,写法都一样,使用双下划线
# 对象属性:
self.__name
#类中的方法:
def __get_shool(self):
#
# 在外部有方法拿到隐藏的属性,是不是也可以修改? 正常的方法是改不了,可以在类中定义一个专门修改的函数
class Students():
    __shool = '社会大学'
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def get_shool(self):
        return self.__shool
    def set_shool(self):
        self.__shool = "清华大学"
stu1 = Students("Hans", 18)
stu1.set_shool()
print(stu1.get_shool())

# 执行结果:
清华大学

# 更好的方法是给set_shool传值
class Students():
    __shool = '社会大学'
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def get_shool(self):
        return self.__shool
    def set_shool(self,shoolname):
        self.__shool = shoolname

stu1 = Students("Hans", 18)
stu1.set_shool("北京大学")
print(stu1.get_shool())
# 执行结果:
北京大学

# 还可以对修改的内容进行判断,现在要修改的是学校名字,按目前写的传什么值都可以,但有些类型不合适用在这个地方比如int类型,所以可以判断一下。
class Students():
    __shool = '社会大学'
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def get_shool(self):
        return self.__shool
    def set_shool(self,shoolname):
        # if type(shoolname) is not str: return 
        if not isinstance(shoolname, str): return
        self.__shool = shoolname

stu1 = Students("Hans", 18)
stu1.set_shool(123)  # 123  不是字符串,直接return返回,所以shool的值还是原来的
print(stu1.get_shool())
# 执行结果:
社会大学

"""
隐藏属性发生了什么?
	1, 在类定义阶段发生了变化,如__shool变成了_Students__shool,也只有在定义阶段发生变化,其他地方都不会发生变化
	2, 隐藏对外不对内
"""

image

7. property装饰器

property是python的一种装饰器,是用来修饰方法的。

上面的例子我们把一些不想对外公开的属性隐蔽起来,而只是提供方法给用户操作(查看get_shool和设置set_shool),在方法里面,我们可以检查参数的合理性等。

class Students():
    __shool = '社会大学'
    def __init__(self,name,age):
        self.__name = name
        self.age = age

    def get_name(self):
        return  self.__name
	
    def set_name(self):
        self.__name="ABC"
        
stu = Students("Hans", 18)
print(stu.get_name())
stu.set_name()
print(stu.get_name())
# 执行结果:
Hans
ABC
# 我们要得到name必须要调用get_name方法,但正常我们取一个属性直接使用.加属性名就可以(stu.name),
# 但现在还要调用一个方法,如何实现即要隐藏属性又要使用.属性获得值,就可以使用@property 
class Students():
    __shool = '社会大学'
    def __init__(self,name,age):
        self.__name = name
        self.age = age

    @property
    def name(self):   # 为了更像stu.name这种方法,把方法名直接改为name
        return  self.__name

stu = Students("Hans", 18)
print(stu.name)
# 执行结果:
Hans

# @property 装饰器会将 name() 方法转化为一个具有相同名称的只读属性的 "getter"

# 在修改的时候也要像查询一样,直接使得.属性的方式
class Students():
    __shool = '社会大学'
    def __init__(self,name,age):
        self.__name = name
        self.age = age

    @property
    def name(self):
        return  self.__name

    @name.setter
    def name(self,name):
        if not isinstance(name, str):
            print("必须为字符串")
            return
        self.__name= name

stu = Students("Hans", 18)
print(stu.name)   # Hans
stu.name = 123	# 必须为字符串,执行到了isinstance
print(stu.name) # Hans

# 修改为一个合法类型:
stu = Students("Hans", 18)
print(stu.name)  # Hans
stu.name = "XYZ"
print(stu.name)	# XYZ
# 可以看到已经修改
# 要使用这种方法,在定义时:
"""
	@property
    def name(self):     	1
        return  self.__name

    @name.setter  2
    def name(self,xxx) 3    
    这三个地方的名字一定要一致。
"""

# 删除一个属性
class Students():
    __shool = '社会大学'
    def __init__(self,name,age):
        self.__name = name
        self.age = age

    @property
    def name(self):
        return  self.__name

    @name.setter
    def name(self,name):
        if not isinstance(name, str):
            print("必须为字符串")
            return
        self.__name= name

    @name.deleter
    def name(self):
        del self.__name
        print("正在删除%s" % self.__name)
stu = Students("Hans", 18)
del stu.name
print(stu.name)
# 执行结果:
正在删除Hans

# 还有一种写法,现在已经不常用了,即定义一个托管属性

class Students():
    __shool = '社会大学'
    def __init__(self,name,age):
        self.__name = name
        self.age = age


    def get_name(self):
        return  self.__name


    def set_name(self,name):
        if not isinstance(name, str):
            print("必须为字符串")
            return
        self.__name= name


    def del_name(self):
        print("正在删除%s" % self.__name)

    # 定义一个托管属性 
    name = property(get_name, set_name, del_name) 


stu = Students("Hans", 18)
print(stu.name)   # 调用get_name 方法
stu.name = "XYZ"  # 调用set_name 方法
print(stu.name)
del stu.name	  # 调用del_name 方法

# 执行结果:
Hans
XYZ
正在删除XYZ

property就是把方法伪装成属性

property详细请看官网:

property

未完待续

Tags: