加入收藏 | 设为首页 | 会员中心 | 我要投稿 北几岛 (https://www.beijidao.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Python 简明教程 --- 20,Python 类中的属性与方法

发布时间:2021-05-21 05:44:07 所属栏目:大数据 来源: https://www.jb51.cc
导读:微信公众号:码农充电站pro 个人主页:https://codeshellme.github.io 与客户保持良好的关系可以使生产率加倍。 —— Larry Bernstain 目录 类中的变量称为 属性@H_403_27@,类中的函数称为 方法@H_403_27@。 类中的属性分为: 实例属性:对象所有,互不干扰

微信公众号:码农充电站pro
个人主页:https://codeshellme.github.io

与客户保持良好的关系可以使生产率加倍。
—— Larry Bernstain

目录

在这里插入图片描述

类中的变量称为属性@H_403_27@,类中的函数称为方法@H_403_27@。

类中的属性分为:

  • 实例属性:对象所有,互不干扰
  • 类属性:类所有,所有对象共享

类中的方法分为:

  • 实例方法:定义中有self@H_403_27@ 参数
  • 类方法:定义中有cls@H_403_27@ 参数,使用@classmethod@H_403_27@ 装饰器
  • 静态方法:定义中即没有self@H_403_27@ 参数,也没有cls@H_403_27@ 参数,使用@staticmethod@H_403_27@ 装饰器

1,实例属性与类属性

类的对象,就是类的一个实例。类的实例属性@H_403_27@被对象所有,包含在每个对象之中,不同的对象之间,互不干扰。类的类属性@H_403_27@被类所有,被包含在类中,是所有的类对象@H_403_27@共享。

在这里插入图片描述

一般情况下,实例属性会在__init__@H_403_27@ 方法中声明并初始化,并且使用self@H_403_27@ 来绑定。而类属性是在类作用域中被声明,并且不使用self@H_403_27@ 来绑定。

例如下面代码中,country@H_403_27@ 为类属性,__name@H_403_27@ 为实例属性:

#! /usr/bin/env python3

class People:

    country = 'china'

    def __init__(self,name):
        self.__name = name
@H_403_27@

访问实例属性时使用对象.属性名@H_403_27@的格式,实例属性属于对象各自的,互不影响:

>>> p1 = People('小明')
>>> p2 = People('小美')
>>> 
>>> p1.get_name()
'小明'
>>> p2.get_name()
'小美'
@H_403_27@

类属性被所有对象共有,一旦被改变,所有对象获取到的值都会被改变。访问类属性时使用类名.属性名@H_403_27@的格式,也可以使用对象.属性名@H_403_27@的格式来访问:

>>> People.country              # 用`类名.属性名`的格式访问
'CHINA'
>>> p1.country                  # 用`对象.属性名`的格式访问
'china'
>>> p2.country
'china'
>>> 
>>> People.country = 'CHINA'    # 类属性的值被改变
>>> p1.country                  # 每个对象获取到的值也会被改变
'CHINA'
>>> p2.country
'CHINA'
@H_403_27@

注意,在使用对象.属性名@H_403_27@的格式访问对象时,不要以这种格式对类属性@H_403_27@进行赋值,否则结果可能不会像你想象的一样:

>>> p1 = People('小明')
>>> p2 = People('小美')
>>> People.country
'china'
>>> p1.country
'china'
>>> p2.country
'china'
>>> p1.country = '中国'   # 使用`对象.属性名`的格式对类对象进行赋值
>>> p1.country           # 只有 p1.country 被改变
'中国'
>>> p2.country           # p2.country 没有被改变
'china'
>>> People.country       # People.country 也没有被改变
'china'
@H_403_27@

从上面代码中可以看到,在Python 中以对象.属性名@H_403_27@格式对类属性@H_403_27@进行赋值时,只有p1.country@H_403_27@ 的值被改变了,p2.country@H_403_27@ 和 People.country@H_403_27@ 的值都没有被改变。

实际上,这种情况下,类属性@H_403_27@的值并没有被改变,而是对象p1@H_403_27@ 中多了一个country@H_403_27@ 实例属性,此后,p1.country@H_403_27@ 访问的是p1@H_403_27@ 的实例属性,p1.country@H_403_27@对属性country@H_403_27@的访问屏蔽了类中的country@H_403_27@属性,而p2.country@H_403_27@ 和 People.country@H_403_27@ 访问的依然是原来的类属性@H_403_27@。

所以,类名.属性名@H_403_27@和对象.属性名@H_403_27@的格式都可以访问类属性@H_403_27@的值,但尽量避免使用对象.属性名@H_403_27@的格式对类属性的值进行赋值,否则可能会发生混乱。

建议:

不管是访问还是改变类属性@H_403_27@的值,都只用类名.属性名@H_403_27@的格式

2,实例方法,类方法,静态方法

Python 类中有三种方法:

  • 实例方法
  • 类方法
  • 静态方法

实例方法@H_403_27@属于对象,方法中都有一个self@H_403_27@ 参数(代表对象本身)。实例方法只能由对象调用,不能通过类名访问。实例方法中可以访问实例属性和类属性。

类方法@H_403_27@属于类,方法中都有一个cls@H_403_27@ 参数(代表类本身)。类方法即可以通过类名访问,也可以通过对象访问,类方法中只能访问类属性,不能访问实例属性。

注意:

Python 解释器在构造类与对象时,类@H_403_27@是先于对象@H_403_27@产生的。

因此,类属性与类方法@H_403_27@是先于实例属性与实例方法@H_403_27@ 产生的。

所以当类方法产生时,还没有实例属性,因此,类方法中不能访问实例属性。

静态方法@H_403_27@中,没有self@H_403_27@ 参数,也没有cls@H_403_27@ 参数。因此,在静态方法中,即不能访问类属性@H_403_27@,也不能访问实例属性@H_403_27@。静态方法可以使用类名访问,也可以使用对象访问。

在Python 中,定义类方法需要用到装饰器@classmethod@H_403_27@,定义静态方法需要用到装饰器@staticmethod@H_403_27@。

实例方法演示

#! /usr/bin/env python3

class People:

    country = 'china'

    def __init__(self,name):
        self.__name = name

    # 实例方法中有self 参数
    def instance_method_test(self):
        # 在实例方法中访问了实例属性和类属性
        print('name:%s country:%s' % (self.__name,People.country))
@H_403_27@

使用:

>>> p = People('小明')
>>> p.instance_method_test()
name:小明 country:china
@H_403_27@

在实例方法中访问了实例属性__name@H_403_27@和类属性country@H_403_27@,均可以被访问。

类方法演示

#! /usr/bin/env python3

class People:

    country = 'china'

    def __init__(self,name):
        self.__name = name

    # 类方法中都有cls 参数
    @classmethod
    def class_method_test1(cls):
        print('在类方法中访问类属性country:%s' % cls.country)

    @classmethod
    def class_method_test2(cls):
        print('在类方法中访问实例属性__name:%s' % self.__name)
@H_403_27@

使用:

>>> p = People('小明')
>>> p.class_method_test1()         # 在类方法中访问类属性,可以
在类方法中访问类属性country:china
>>>
>>> p.class_method_test2()         # 在类方法中访问实例属性,出现异常
Traceback (most recent call last):
  File "<stdin>",line 1,in <module>
  File "/home/wp/to_beijing/People.py",line 18,in class_method_test2
    print('在类方法中访问实例属性__name:%s' % self.__name)
NameError: name 'self' is not defined
@H_403_27@

从上面代码中可以看到,在类方法中可以访问类属性,但在类方法中访问实例属性,会出现异常。

静态方法演示

#! /usr/bin/env python3

class People:

    country = 'china'

    def __init__(self,name):
        self.__name = name

    # 静态方法中即没有self 参数也不没有cls 参数
    @staticmethod
    def static_method_test1():
        print('在静态方法中访问类属性country:%s' % cls.country)

    @staticmethod
    def static_method_test2():
        print('在静态方法中访问实例属性__name:%s' % self.__name)
@H_403_27@

使用:

>>> p = People('小明')
>>> p.static_method_test1()      # 在静态方法中访问类属性,出现异常
Traceback (most recent call last):
  File "<stdin>",line 14,in static_method_test1
    print('在静态方法中访问类属性country:%s' % cls.country)
NameError: name 'cls' is not defined
>>>
>>> p.static_method_test2()     # 在静态方法中访问实例属性,出现异常
Traceback (most recent call last):
  File "<stdin>",in static_method_test2
    print('在静态方法中访问实例属性__name:%s' % self.__name)
NameError: name 'self' is not defined
@H_403_27@

从上面代码中可以看到,在静态方法中无论访问实例方法还是类方法,都会出现异常。

3,专有方法

我们之前讲到过的魔法方法@H_403_27@,即以双下划线__@H_403_27@开头且结尾的方法__xxx__@H_403_27@,就是专有方法@H_403_27@。这些方法都被Python 赋予了特殊的含义,用户可以根据需要,来实现这些方法。

下面我们介绍一些 Python 中常见的专有方法。

__len__@H_403_27@ 方法

实现该方法的类的对象,可以用len()@H_403_27@ 函数计算其长度。

__str__@H_403_27@ 方法

实现该方法的类的对象,可以转化为字符串。

__call__@H_403_27@ 方法

实现该方法的类的对象,可以像函数一样调用。

__iter__@H_403_27@ 方法

实现该方法的类的对象,是可迭代的。

__setitem__ @H_403_27@ 方法

实现该方法的类的对象,可以用索引@H_403_27@的方式进行赋值。

__getitem__@H_403_27@ 方法

实现该方法的类的对象,可以用索引@H_403_27@的方式进行访问。

__contains__@H_403_27@ 方法

实现该方法的类的对象,可以进行in@H_403_27@ 运算。


__add__@H_403_27@ 方法

实现该方法的类的对象,可以进行加+@H_403_27@运算。

__sub__@H_403_27@ 方法

实现该方法的类的对象,可以进行减-@H_403_27@运算。

__mul__@H_403_27@ 方法

实现该方法的类的对象,可以进行乘*@H_403_27@运算。

__div__@H_403_27@ 方法

实现该方法的类的对象,可以进行除/@H_403_27@运算。

__pow__@H_403_27@ 方法

实现该方法的类的对象,可以进行乘方@H_403_27@运算。

__mod__@H_403_27@ 方法

实现该方法的类的对象,可以进行取模@H_403_27@运算。


__eq__@H_403_27@ 方法

实现该方法的类的对象,可以进行相等==@H_403_27@比较。

__ne__@H_403_27@ 方法

实现该方法的类的对象,可以进行不等于!=@H_403_27@比较。

__gt__@H_403_27@ 方法

实现该方法的类的对象,可以进行大于>@H_403_27@比较。

__ge__@H_403_27@ 方法

实现该方法的类的对象,可以进行大于等于>=@H_403_27@比较。

__lt__@H_403_27@ 方法

实现该方法的类的对象,可以进行小于<@H_403_27@比较。

__le__@H_403_27@ 方法

实现该方法的类的对象,可以进行小于等于<=@H_403_27@比较。

(完。)


推荐阅读:

Python 简明教程 --- 15,Python 函数

Python 简明教程 --- 16,Python 高阶函数

Python 简明教程 --- 17,Python 模块与包

Python 简明教程 --- 18,Python 面向对象

Python 简明教程 --- 19,Python 类与对象


欢迎关注作者公众号,获取更多技术干货。

码农充电站pro

(编辑:北几岛)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读