美文网首页程序员
Python 类和实例

Python 类和实例

作者: keinYe | 来源:发表于2018-12-27 21:17 被阅读2次
    image

    类是实例的模板,实例是依据类建立的对象。类和实例是面向对象编程最重要的两个概念。

    根据同一个类建立的实例(或对象)具有相同的方法,但是他们各自可以有不同的数据。

    类是对同一种事物的抽象(即一种事物所具有的相同部分),在 python 中使用关键字 class 来定义一个类,下面是一个最简单的类的定义

    class Person:
        pass
    

    以上代定义了一个空的类,该类不存在任何的属性和方法。从属于类的变量我们称之为类的属性,从属于类的函数我们称之为类的方法。

    属性

    属性有两种类型,从属于某一个类本身或从属于摸一个类的实例。从属于类的示例的我们称之为示例属性,从属于类本身的我们称之为类属性。

    通过实例变量或 self 关键字可以给实例绑定属性

    #!/usr/bin/env python3
    # -*- coding:utf-8 -*-
    
    class Person:
        def __init__(self, name):
            self.name = name
            
    person = Person('Bob')
    person.age = 31
    
    print(person.name)
    print(person.age)
    print(Person.name)
    print(Person.age)
    

    以上代码执行结果如下

    Bob
    31
    Traceback (most recent call last):
      File "class.py", line 13, in <module>
        print(Person.name)
    AttributeError: type object 'Person' has no attribute 'name'
    

    以上代码使用实例 person 和 self 分别定义了属性 age 和 name,在访问属性时通过实例 person 可正常获取 age 和 name 的值,但是当使用类 Person 来访问属性 age 和 name 是 python 提示 type object 'Person' has no attribute 'name',即类 Person 不存在属性 name。

    如果类 Person本身需要一个属性,可以直接在类中定义,它属于 Person 类本身,所有通过 Person 实例化的示例均可访问该属性。

    #!/usr/bin/env python3
    # -*- coding:utf-8 -*-
    
    class Person:
        name = 'Person'
        
        def __init__(self, age):
            self.age = age
    
    person1 = Person(23)
    person2 = Person(33)
    print(Person.name)
    print(person1.name)
    print(person1.age)
    print(person2.name)
    print(person2.age)
    

    以上代码执行结果如下

    Person
    Person
    23
    Person
    33
    

    通过以上代码可以看出属性 name 直接在类中进行定义,不仅类 Person 可访问该属性,Person 的实例 person1 和 person2 同样可以访问该属性。

    示例属性仅在该示例内可以使用。类属性不仅类可使用,通过该类实例化的实例同样可使用。

    既然类的属性在类的实例中可使用,那么实例属性和类属性相同此时会发生什么呢,让我们来看以下代码。

    #!/usr/bin/env python3
    # -*- coding:utf-8 -*-
    
    class Person:
        name = 'Person'
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
    person = Person('Bob', 33)
    print(person.name)
    print(person.age)
    print(Person.name)
    

    以上代码运行结果如下

    Bob
    33
    Person
    

    通过以上代码可以看出,当类属性和实例属性相同时,实例属性并不会覆盖类属性的值,通过实例访问时获取的是实例属性,通过类访问时获取到的是类属性。

    在编写代码时要尽量避免出现类属性和实例属性相同的情况,因为此时实例属性会覆盖类属性,可能会得到与预期不同的结果。

    在以上我们看到的代码中类或示例的属性对所有人都是可见,事实上使用类的初衷是隐藏内部的数据,通过方法来操作数据,从目前来说这与我们的初衷相悖。那么如果要隐藏内部属性该怎么做呢?我们可以在属性的名称前加上两个下划线,在 Python 中,实例的变量名如果以 __ 开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问。我们将以上代码修改如下:

    #!/usr/bin/env python3
    # -*- coding:utf-8 -*-
    
    class Person:
        def __init__(self, name, age):
            self.__name = name
            self.__age = age
            
        def print_age():
            print("%s age is %s" % (self.name, self.age))
    
    person = Person('Bob', 33)
    person.print_age()
    print(person.__age)
    

    以上代码运行结果如下

    Bob age is 33
    Traceback (most recent call last):
      File "<stdin>", line 14, in <module>
    AttributeError: 'Person' object has no attribute '__age'
    

    如上所示类的属性不能直接访问,这样就确保了外部代码不能随意修改对象内部的状态,这样通过访问限制的保护,代码更加健壮。但是如果想要获取或修改内部属性改怎么处理,我们可以通过增加 get 和 set 方法来实现。

    #!/usr/bin/env python3
    # -*- coding:utf-8 -*-
    
    class Person:
        def __init__(self, name, age):
            self.__name = name
            self.__age = age
            
        def print_age():
            print("%s age is %s" % (self.name, self.age))
            
        def get_name():
            return self.__name
        
        def get_age():
            return self.__age
            
        def set_name(name):
            self.__name = name
        
        def set_age(age):
            self.__age = age
    
    person = Person('Bob', 33)
    person.print_age()
    print(person,get_age())
    person.set_age(34)
    print(person,get_age())
    

    以上代码运行结果如下

    Bob age is 33
    33
    34
    

    方法

    类的方法既类中的函数,和普通函数不同的是类的方法第一个参数是 self,但是在调用该方法时不需要传入 self。除此之外,类的方法和普通函数没有什么区别,因此你仍然可以用默认参数、可变参数、关键字参数和命名关键字参数。

    方法中的 self 是必须的,即使没有其它参数也必须有 self 参数。

    在前面的代码中总是看到 __init__ 方法,__init__ 方法是类的一个特殊方法,它有一个名字叫初始化函数,它在类被实例化时立即运行,它可以对任何你需要操作的目标对象进行初始化操作。就像前面的示例中所使用的,你不必显式调用该函数,在类的实例化过程中 python 会自动调用该函数。

    需要注意的是在 __init__ 方法前后分别有两个下划线。

    相关文章

      网友评论

        本文标题:Python 类和实例

        本文链接:https://www.haomeiwen.com/subject/ogodlqtx.html