Python笔记_第三篇_面向对象_8.对象属性和类属性及其动态添加属性和方法

1. 对象属性和类属性

  我们之前接触到,在类中,我们一般都是通过构造函数的方式去写一些类的相关属性。在第一次介绍类的时候我们把一些属性写到构造函数外面并没有用到构造函数,其实当时在写的时候,就是在给类进行属性的添加,类也是具有属性。

  举例说明1:

class Person(object):
    """
    写在这个位置的叫做类属性
    """
    name = "Person"

    def __init__(self,name):
        """
        写在这个位置的叫做对象属性
        """
        self.name = name

print(Person.name)
# Person

per = Person("Tom")
print(per.name)
# Tom

  

  举例说明2:如果没有对象属性,打印的是类属性,对象属性还可以通过类属性进行添加。

# 如果没有对象属性的,打印的是类属性,对象属性可以通过类属性添加。
class Person(object):
    """
    写在这个位置的叫做类属性
    """
    name = "Person"

    def __init__(self):
        """
        写在这个位置的叫做对象属性
        """
        pass

per = Person()
# 动态的通过类属性给对象属性添加属性,只针对于当前对象生效,对于类创建的其他对象没有作用
per.name = "Thomas"
print(per.name)
# Thomas

per.age = 18
print(per.age)
# 18

# 删除对象中的name属性,再调用会使用同名的类属性。
del per.name
print(per.name)
# Person

  注意:以后千万不要将对象属性与类属性重名,因为对象属性会屏蔽掉类属性。但是当删除对象属性后,再使用又能使用类属性的属性了。

2. 动态给实例添加属性和方法

  用到一个模块:types中的MethodType方法

  格式:新方法 = MethodType(原方法,类名)

  举例说明3:

from types import MethodType

class Person(object):
    pass

per = Person()
# 动态添加属性,这体现了动态语言的特点——灵活。
per.name = "Tom"
print(per.name)
print(type(per.name))
# Tom
# <class 'str'>

# 动态添加方法
def say(self):
    print("my name is " + self.name)

per.speak = MethodType(say,per) # MethodType其实就是个添加函数,生成一个新的函数叫speak
per.speak()
# my name is Tom

# Tom
# <class 'str'>
# my name is Tom
# 100

3. 限制实例添加属性:

  如果我们想要限制实例的属性怎么办,这里就用到了一个重载__slots__

  格式:

  __slots__(只允许添加的属性,字符串格式)

  举例说明4:

from types import MethodType

class Person(object):
    # 限制添加属性,(只允许添加的属性)
    __slots__ = ("name","age","speak") # 只允许添加的属性

per = Person()
per.height = 170
# 不允许添加height这个属性AttributeError: 'Person' object has no attribute 'height'
print(per.height)