前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python 类和实例

Python 类和实例

作者头像
keinYe
发布2019-08-01 11:05:08
6520
发布2019-08-01 11:05:08
举报
文章被收录于专栏:keinYekeinYe
类是实例的模板,实例是依据类建立的对象。类和实例是面向对象编程最重要的两个概念。

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

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

代码语言:javascript
复制
class Person:
    pass

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

属性

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

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

代码语言:javascript
复制
#!/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)

以上代码执行结果如下

代码语言:javascript
复制
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 实例化的示例均可访问该属性。

代码语言:javascript
复制
#!/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)

以上代码执行结果如下

代码语言:javascript
复制
Person
Person
23
Person
33

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

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

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

代码语言:javascript
复制
#!/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)

以上代码运行结果如下

代码语言:javascript
复制
Bob
33
Person

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

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

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

代码语言:javascript
复制
#!/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)

以上代码运行结果如下

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

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

代码语言:javascript
复制
#!/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())

以上代码运行结果如下

代码语言:javascript
复制
Bob age is 33
33
34

方法

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

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

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

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

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-12-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 keinYe 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
    • 属性
      • 方法
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档