Python-实例属性和类属性

  1. 实例属性和类属性
    1. 实例属性指的是实例对象所绑定的属性
    2. 类属性指的是类对象所绑定的属性

实例属性和类属性

实例属性指的是实例对象所绑定的属性

绑定实例属性(给实例绑定属性)的两种方式:
1、在类对象的内部(方法中)

  • 语法格式:self.属性名 = 属性值
    推荐在特殊方法__init__中进行绑定,这样,在创建实例对象后就会自动调用特殊方法__init__对实例对象进行初始化,从而绑定实例属性。如果在其他方法中进行绑定,可能需要手动调用方法后才会绑定。

2、在类对象外部进行绑定
python是动态语言,所以,在实例对象创建之后,可以对其动态的绑定属性

  • 语法格式:实例对象.属性名 = 属性值
    如果指定名称的实例属性已经存在, 如果使用上述方式,则是对实例属性进行修改

访问实例属性的方式:
1、在类对象的内部(方法中)

  • 语法格式:self.属性名

2、在类对象外部

  • 语法格式:实例对象.属性名

之所以添加前缀“self”或“实例对象”,是为了表明实例属性被哪个实例对象所绑定

#!/usr/bin/python3

class animals(object):
    def __init__(self, name, age):
        # 在类对象的内部(方法中)绑定实例属性
        self.name = name
        self.age = age
    def run(self):
        # 在类对象的内部(方法中)访问实例属性
        print('{} is running'.format(self.name))


dog = animals('kk', 12)

# 在类对象的外部访问实例属性
print(dog.name)
print(dog.age)


dog.run()

同一个类对象的不同的实例对象所绑定的实例属性是相互独立的,也就是说,给一个实例对象绑定的实例属性,对于另外一个实例对象是不起作用的

#!/usr/bin/python3

class animals(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age


dog = animals('wangcai', 10)
cat = animals('miaomiao', 7)

print('dog\'name: %s' %(dog.name))
print('dog\'age: %s' %(dog.age))


print('cat\'name: %s' %(cat.name))
print('cat\'age: %s' %(cat.age))

##修改狗的名字为wangwang
dog.name = 'wangwang'

print('dog\'name: %s' %(dog.name))
print('dog\'age: %s' %(dog.age))


print('cat\'name: %s' %(cat.name))
print('cat\'age: %s' %(cat.age))
[root@lyucan ~]# ./5.py
dog'name: wangcai
dog'age: 10
cat'name: miaomiao
cat'age: 7
dog'name: wangwang
dog'age: 10
cat'name: miaomiao
cat'age: 7

类属性指的是类对象所绑定的属性

绑定类属性(给类对象绑定属性)的方式有两种:
1、在类对象的内部(方法外)

  • 语法格式:属性名 = 属性值

2、在类对象的外部
python是动态语言,所以,在类对象创建以后,可以对其动态的绑定属性。

  • 语法格式:类对象名.属性名 = 属性值
    如果指定名称的类属性已经存在,则是对类属性进行修改

访问类属性的两种方式:
1、在类对象的内部(方法中)

  • 语法格式:类对象.属性名
    2、在类对象的外部
  • 语法格式:类对象.属性名 或:实例对象.属性名
    类对象的所有实例对象都有一个指向类对象的指针,所以,类对象的所有实例对象都可以访问类属性。但是当修改其中一个属性后,另一个属性不会随之更改。

之所以添加前缀“类对象”,是为了表明类属性被哪个类对象所绑定

#!/usr/bin/python3

class animals(object):
    # 在类对象的内部(方法外)绑定类属性
    animals_type = 'pets'
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def print_class(self):
        # 在类对象的内部(方法中)访问类属性
        print(animals.animals_type)


dog = animals('wangcai', 10)
dog.print_class()

# 在类对象外部访问类属性,使用类名或实例名
print(animals.animals_type)
print(dog.animals_type)
[root@lyucan ~]# ./6.py
pets
pets
pets

访问实例属性和类属性都可以通过“实例对象.属性名”来访问。当通过“实例对象.属性名”的方式访问属性时,会先查找指定的实例对象中有没有指定名称的实例属性,如果没有,再查找对应的类对象中有没有指定名称的类属性。所以当通过这种方式访问属性时,如果实例属性和类属性同名,那么实例属性会屏蔽掉类属性。

当通过“实例对象.属性名 = 属性值”绑定属性时,这里的属性只表示实例属性,因为类属性没有这样的绑定方式,所以只会查找指定的实例对象有没有绑定指定名称的实例属性,如果没有则进行绑定,如果绑定了,则对属性值进行修改。

由于Python是动态语言,根据类创建的实例可以任意绑定属性。
给实例绑定属性的方法是通过实例变量,或者通过self变量:

class Student(object):
def __init__(self, name):
self.name = name


s = Student('Bob')
s.score = 90

但是,如果Student类本身需要绑定一个属性呢?可以直接在class中定义属性,这种属性是类属性,归Student类所有:

class Student(object):
name = 'Student'

当我们定义了一个类属性后,这个属性虽然归类所有,但类的所有实例都可以访问到。来测试一下:

>>> class Student(object):
... name = 'Student'
...
>>> s = Student() # 创建实例s
>>> print(s.name) # 打印name属性,因为实例并没有name属性,所以会继续查找class的name属性 Student
>>> print(Student.name) # 打印类的name属性 Student
>>> s.name = 'Michael'# 给实例绑定name属性
>>> print(s.name) # 由于实例属性优先级比类属性高,因此,它会屏蔽掉类的name属性 Michael
>>> print(Student.name) # 但是类属性并未消失,用Student.name仍然可以访问 Student
>>> del s.name # 如果删除实例的name属性
>>> print(s.name) # 再次调用s.name,由于实例的name属性没有找到,类的name属性就显示出来了 Student

从上面的例子可以看出,在编写程序的时候,千万不要把实例属性和类属性使用相同的名字,因为相同名称的实例属性将屏蔽掉类属性,但是当你删除实例属性后,再使用相同的名称,访问到的将是类属性。
cd084092-7d6d-4b50-9e8f-ad89033e40c6-image.png


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 289211569@qq.com