zoukankan      html  css  js  c++  java
  • Python3简明教程(十一)—— 类

    本节中将通过定义一些简单的 Python 类,来学习 Python 面向对象编程的基本概念。

    定义类

    在写你的第一个类之前,你应该知道它的语法。我们以下面这种方式定义类:

    class nameoftheclass(parent_class):
        statement1
        statement2
        statement3

    在类的声明中你可以写任何 Python 语句,包括定义变量(在类中称为属性)、定义函数(在类中我们称为方法)。

    >>> class MyClass(object):
    ...     """A simple example class"""
    ...     i = 12345
    ...     def f(self):
    ...         return 'hello world'

    __init__方法

    类的实例化使用函数符号。只要将类对象看作是一个返回新的类实例的无参数函数即可。例如(假设沿用前面的类):

    x = MyClass()

    以上创建了一个新的类实例并将该对象赋给局部变量 x

    这个实例化操作创建一个空的对象。很多类都倾向于将对象创建为有初始状态的。因此类可能会定义一个名为 __init__() 的特殊方法,像下面这样:

    def __init__(self):
        self.data = []

    类定义了 __init__() 方法的话,类的实例化操作会自动为新创建的类实例调用 __init__() 方法。所以在下例中,可以这样创建一个新的实例:

    x = MyClass()

    当然,出于弹性的需要,__init__() 方法可以有参数。事实上,参数通过__init__() 传递到类的实例化操作上。例如:

    >>> class Complex:
    ...     def __init__(self, realpart, imagpart):
    ...         self.r = realpart
    ...         self.i = imagpart
    ...
    >>> x = Complex(3.0, -4.5)
    >>> x.r, x.i
    (3.0, -4.5)

    继承

    当一个类继承另一个类时,它将继承父类的所有功能(如变量和方法)。这有助于重用代码。

    在下一个例子中我们首先创建一个叫做 Person 的类,然后创建两个派生类 Student 和 Teacher。当两个类都从 Person 类继承时,它们的类除了会有 Person 类的所有方法还会有自身用途的新方法和新变量。

    代码写入文件 /home/shiyanlou/student_teacher.py

    #!/usr/bin/env python3
    
    class Person(object):
        """
        返回具有给定名称的 Person 对象
        """
    
        def __init__(self, name):
            self.name = name
    
        def get_details(self):
            """
            返回包含人名的字符串
            """
            return self.name
    
    
    class Student(Person):
        """
        返回 Student 对象,采用 name, branch, year 3 个参数
        """
    
        def __init__(self, name, branch, year):
            Person.__init__(self, name)
            self.branch = branch
            self.year = year
    
        def get_details(self):
            """
            返回包含学生具体信息的字符串
            """
            return "{} studies {} and is in {} year.".format(self.name, self.branch, self.year)
    
    
    class Teacher(Person):
        """
        返回 Teacher 对象,采用字符串列表作为参数
        """
        def __init__(self, name, papers):
            Person.__init__(self, name)
            self.papers = papers
    
        def get_details(self):
            return "{} teaches {}".format(self.name, ','.join(self.papers))
    
    
    person1 = Person('Sachin')
    student1 = Student('Kushal', 'CSE', 2005)
    teacher1 = Teacher('Prashad', ['C', 'C++'])
    
    print(person1.get_details())
    print(student1.get_details())
    print(teacher1.get_details())

    运行程序:

    shiyanlou:~/ $ ./student_teacher.py[17:34:31]
    Sachin
    Kushal studies CSE and is in 2005 year.
    Prashad teaches c,c++.

    在这个例子中你能看到我们是怎样在 Student 类和 Teacher 类中调用 Person 类的 __init__ 方法。

    我们也在 Student 类和 Teacher 类中重写了 Person 类的 get_details() 方法。因此,当我们调用 student1 和 teacher1 的 get_details() 方法时,使用的是各自类(Student 和 Teacher)中定义的方法。

    多继承

    一个类可以继承自多个类,具有父类的所有变量和方法,语法如下:

    class MyClass(Parentclass1, Parentclass2,...):
        def __init__(self):
            Parentclass1.__init__(self)
            Parentclass2.__init__(self)
            ...
            ...

    删除对象

    现在我们已经知道怎样创建对象,现在我们来看看怎样删除一个对象。我们使用关键字 del 来做到这个。

    >>> s = "I love you"
    >>> del s
    >>> s
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    NameError: name 's' is not defined

    del 实际上使对象的引用计数减少一,当对象的引用计数变成零的时候,垃圾回收器会删除这个对象。

    属性(sttributes)读取方法

    在 Python 里请不要使用属性(attributes)读取方法(getters和 setters)。如果你之前学过其它语言(比如 Java),你可能会想要在你的类里面定义属性读取方法。请不要这样做,直接使用属性就可以了,就像下面这样:

    >>> class Student(object):
    ...     def __init__(self, name):
    ...         self.name = name
    ...
    >>> std = Student("Kushal Das")
    >>> print(std.name)
    Kushal Das
    >>> std.name = "Python"
    >>> print(std.name)
    Python

    装饰器

    你可能想要更精确的调整控制属性访问权限,你可以使用 @property 装饰器,@property 装饰器就是负责把一个方法变成属性调用的。

    下面有个银行账号的例子,我们要确保没人能设置金额为负,并且有个只读属性 cny 返回换算人民币后的金额。

    代码写入文件 /home/shiyanlou/property.py

    #!/usr/bin/env python3
    
    class Account(object):
        """账号类,
        amount 是美元金额.
        """
        def __init__(self, rate):
            self.__amt = 0
            self.rate = rate
    
        @property
        def amount(self):
            """账号余额(美元)"""
            return self.__amt
    
        @property
        def cny(self):
            """账号余额(人民币)"""
            return self.__amt * self.rate
    
        @amount.setter
        def amount(self, value):
            if value < 0:
                print("Sorry, no negative amount in the account.")
                return
            self.__amt = value
    
    if __name__ == '__main__':
        acc = Account(rate=6.6) # 基于课程编写时的汇率
        acc.amount = 20
        print("Dollar amount:", acc.amount)
        print("In CNY:", acc.cny)
        acc.amount = -100
        print("Dollar amount:", acc.amount)

    运行程序:

    shiyanlou:~/ $ ./property.py
    Dollar amount: 20
    In CNY: 132.0
    Sorry, no negative amount in the account.
    Dollar amount: 20

    总结

    本实验我们了解了类的定义,类的继承以及多继承,并且最后我们还接触了装饰器这个概念,本质上,装饰器也是一种高阶函数。

    参考链接:https://www.shiyanlou.com/courses/596

  • 相关阅读:
    Python 练习册,每天一个小程序----第0000题
    CMDB系统原创开发
    203.pycharm连接远程终端
    202. 菜鸟学习k8s安装1
    (高并发)防止重复点击,屏蔽多次无效请求的解决方案(优惠劵被重复领取,恶意撸羊毛)
    SSM批量插入和修改实现实例
    java服务器访问其他服务器工具类编写
    递归实例,欢迎大家修改优化
    SpringJDBC
    Spring入门
  • 原文地址:https://www.cnblogs.com/lfri/p/10384954.html
Copyright © 2011-2022 走看看