成员属性辨析:Python 中的实例属性与静态属性

参考

项目描述
Python 官方文档https://docs.python.org/zh-cn/3/
搜索引擎GoogleBing

描述

项目描述
PyCharm2023.1 (Professional Edition)
Python3.10.6

成员属性

在 Python 中,成员属性指的是 对象 所拥有的 属性,成员属性用于表示和存储类或对象的 状态。Python 中的成员属性可以分为两种类型,即 实例属性静态属性

实例属性(Instance Attributes)

实例属性是绑定在 特定对象 上的属性,由同一个类实例化产生的每个对象都可以具有 不同的实例属性值。实例属性在类的方法中通过 self 关键字进行 访问设置,每个对象都拥有自己的一组实例属性。

举个栗子

class MyClass:
    # 类的初始化函数,在类被实例化为对象时立即执行。
    def __init__(self, name, age, sex):
        # 此处的 self 为由类实例化的对象本身
        self.name = name
        self.age = age
        self.sex = sex


# 将 MyClass 进行实例化操作,并为两者的属性赋予不同的值
redHeart = MyClass('RedHeart', 18, 'male')
twoMoons = MyClass('TwoMoons', 18, 'female')

# 访问不同实例化对象的实例属性
print(f'''Name: {redHeart.name}
Age: {redHeart.age}
Sex: {redHeart.sex}
''')

print(f'''Name: {twoMoons.name}
Age: {twoMoons.age}
Sex: {twoMoons.sex}
''')

执行效果

Name: RedHeart
Age: 18
Sex: male

Name: TwoMoons
Age: 18
Sex: female

注:

  1. 实例属性仅能够通过 类的实例对象 进行 访问 修改,通过 来访问或修改实例属性是 不可行的。对此,请参考如下示例:

    class RedHeart:
        def __init__(self):
            self.name = 'RedHeart'
            self.age = 18
            self.sex = 'male'
    
    
    # 尝试通过类的实例化对象访问实例属性
    redHeart = RedHeart()
    print(redHeart.name)
    
    # 尝试通过类访问实例属性将产生 AttributeError 异常错误信息,其中包括如下内容
    # AttributeError: type object 'RedHeart' has no attribute 'name'
    print(RedHeart.name)
    

    执行效果

    RedHeart
    
  2. 实例属性与类的实例对象相绑定,你无法通过更改某一个类的一个实例对象的实例属性来影响其他实例对象的实例属性,即使该实例属性的值为一个 可变对象。对此,请参考如下示例:

    class Fruits:
        def __init__(self):
            self.strain = []
    
    
    red = Fruits()
    green = Fruits()
    
    # 通过 Fruits 类的不同实例对象来对实例属性进行修改
    red.strain.append('cherry')
    green.strain.append('watermelon')
    
    # 不同的实例对象对实例属性的修改仅影响自身
    print(red.strain)
    print(green.strain)
    

    执行效果

    ['cherry']
    ['watermelon']
    

静态属性(Static Attributes)

在 Python 中,静态属性是 类级别 的属性,它属于类本身而不是类的实例。静态属性在所有类的实例之间共享,并且可以通过类或实例使用 点运算符 来访问。静态属性在类定义过程中通过 直接在类中而不是在类的方法中定义 的方式来进行声明。对此,请参考如下示例:

class MyClass:
    # 声明静态属性
    name = 'RedHeart'


redHeart = MyClass()
twoMoons = MyClass()

# 通过实例对象来访问其相关类的静态属性
print(redHeart.name)
print(twoMoons.name)

# 通过类来访问或修改其静态属性
print(MyClass.name)
MyClass.name = 'TwoMoons'

# 通过实例对象来访问其相关类的静态属性
print(redHeart.name)
print(twoMoons.name)

执行效果

RedHeart
RedHeart
RedHeart
TwoMoons
TwoMoons

注:

  1. 当你通过实例对象使用 点运算符 操作静态属性的过程中,使用 赋值运算符(包括但不限于 =、+=、&=) 将创建一个与被操作静态属性同名的实例属性。对此,请参考如下示例:

    class MyClass:
        name = 'Hello '
    
    
    redHeart = MyClass()
    twoMoons = MyClass()
    
    redHeart.name = 'RedHeart'
    print(redHeart.name == MyClass.name)
    
    # twoMoons.name += 'World' 
    # 可以拆解为
    # twoMoons.name = twoMoons.name + 'World'
    # 其中,第一个 twoMoons.name 为实例属性
    # 第二个 twoMoons.name 对应类提供的静态属性
    twoMoons.name += 'World'
    print(twoMoons.name == MyClass.name)
    
    print(MyClass.name)
    print(twoMoons.name)
    

    执行效果

    False
    False
    Hello 
    Hello World
    
  2. 当存在 相同名称 的实例属性与静态属性时,类仍旧 仅能够 访问或修改静态属性,而实例对象则 优先 访问或修改实例属性。对此,请参考如下示例:

    class MyClass:
        target = 'Hello China'
    
        def __init__(self):
            self.target = 'Hello World'
    
    
    myClass = MyClass()
    
    # 实例对象将优先访问实例属性
    print(myClass.target)
    
    # 删除实例对象的实例属性
    del myClass.target
    
    # 在与静态属性同名的实例属性被删除后,
    # 静态属性将变得能够被访问。
    print(myClass.target)
    

    执行效果

    Hello World
    Hello China
    
  3. 静态属性仅能够通过类或实例对象通过使用点运算符进行访问。对此,请参考如下示例:

    target = 'Hello China'
    
    
    class MyClass:
        target = 'Hello World'
    
        def echo(self):
            print(f'【全局变量】 {target}')
            print(f'【静态属性】 {self.target}')
            print(f'【静态属性】 {MyClass.target}')
    
    
    myClass = MyClass()
    myClass.echo()
    

    执行效果

    【全局变量】 Hello China
    【静态属性】 Hello World
    【静态属性】 Hello World
    

实例属性与局部变量

形参 self

在 Python 中,类中的方法的第一个参数 通常 被命名为 self,这个参数表示 对实例对象自身的引用self 在方法定义时 必须 存在,在调用方法时无需显式为 self 形参传递实参,Python 将自动完成这项工作。对此,请参考如下示例:

class MyClass:
    def get_self(self):
        return self


myClass = MyClass()
# 判断两者的身份标识(对象存放的内存空间的内存地址)
# 是否相同。若相同,则两者为同一对象。
print(myClass is myClass.get_self())

执行效果

True

self 参数的作用是指示属性或方法属于实例对象本身,通过 self 可以访问和操作实例对象的属性和方法。

不只是 self

在 Python 中,类中的方法的第一个参数通常被命名为 self,尽管这个名称并 不是强制的,但它是 一种广泛接受的约定self 表示对类实例自身的引用,并用于访问和操作实例的属性和方法。虽然约定是将第一个参数命名为 self,但 实际上 你可以使用 任何合法的变量名 作为第一个参数。
如果你使用其他名称替代常用的 self,虽然 Python 解释器并不会对此产生异常错误,但这一行为会让其他开发者感到困惑。

实例属性与局部变量

类的方法内部,通过 self 定义的变量是实例变量,而未通过 self 定义的变量是局部变量。

实例属性 是绑定到实例对象上的变量,实例属性可以在 整个实例对象 中访问和使用。
局部变量 是在方法内部定义的变量,局部变量 只在当前方法的作用域内有效。局部变量的作用域仅限于所属的方法,方法外部无法直接访问局部变量。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BinaryMoon

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值