2022年 11月 3日

Python类成员

1.类成员

  • 类成员包括:类属性和类方法属于类,可以不实例化对象,直接通过类名调用,这些类成员为所有对象共有,一般用于对象间通信。
class Person:
    # 类属性必须在方法外面定义
    name = '姚圈圈'
    gender = '男'
    __age = 23            # 私有属性

    def __init__(self,name,age):
        self.name = name  # 实例属性或成员属性
        self.__age = age

# 实例化对象
qiao = Person('乔鸡鸡',20)
liu = Person('刘鸡鸡',30)

# 类属性调用方式:
# 类名.属性名
print(Person.name)         # 输出:姚圈圈
print(qiao.gender)         # 输出男

# 如果成员属性名和类属性名冲突,优先访问成员属性,成员属性屏蔽类属性
print(qiao.name)           # 输出:乔鸡鸡
print(liu.name)            # 输出:刘鸡鸡

# 私有属性不能通过类名直接访问
# print(Person.__age)        # AttributeError: type object 'Person' has no attribute '__age'

# 删除对象的属性
del liu.name
print(liu.name)              # 访问的是类属性 输出:姚圈圈

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

2.类方法和静态方法

  • 类方法属于类,为所有对象共有,可以通过类名对象调用
  • 类方法可以用来访问属性类
  • 静态方法属于类的作用域内的全局函数
  • 类方法和静态方法的区别,类方法第一个参数是类对象,由系统传入,静态方法没有
  • 共同点:静态方法和类方法都可以通过类名直接调用,属于类不属于对象
class Date:
    def __init__(self,year,moth,day):
        self.year = year
        self.moth = moth
        self.day = day

    @classmethod       # 类方法 直接调用
    def date_from_string(cls,date_string):
        '''
        :param cls 类对象,和类名作用一样
        :param date_string: 日期字符串,格式必须是yyyy-mm-dd
        :return: 日期对象
        '''
        year,moth,day = tuple(map(int,date_string.split("-")))
        return cls(year,moth,day)

    # 静态方法
    @staticmethod
    def is_validz_date(date_string):
        year,moth,day = tuple(map(int,date_string.split("-")))
        return year >= 0 and 1 < moth <= 12 and 0 < day <= 31

d1 = Date.date_from_string('2020-03-04')
print(d1.year,d1.moth,d1.day)            # 输出:2020 3 4
print(Date.is_validz_date('2020-03-05')) # 返回:True
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

3.类成员的动态绑定

  • 实例的属性和方法可以动态绑定,可以在程序运行期间可以给程序增加功能,对静态语言来来说无异于天方夜谭,对Python来说一切皆有可能
  • 给对象动态添加的属性只属于这个对象,其它对象没有该属性
  • 使用__slots__限制属性的动态绑定
class Cat:
    __slots__ = ('gender', 'name', 'age', 'kind')  # 这个个类的对象只能有这些属性

cat = Cat()

# 动态添加属性
cat.name = 'tom'
cat.gender = '公'

# 不能添加这个属性,语法错误
# cat.weight = 8  AttributeError: 'Cat' object has no attribute 'weight'

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

4.对象计数

    num = 0
    def __init__(self):
        # self.__class__当前对象所属的类
        self.__class__.num += 1
        
        # 不能通过self修改类属性
        # self.num = 10  # 定义了一个对象属性、

    def __del__(self):
        self.__class__.num -= 1

# 如果统计一个类实例化了多少个对象
d1 = Dog()
d2 = Dog()
d2.num = 100  #动态添加了一个对象属性

del d2
d3 = Dog()
print(Dog.num)  # 输出 2
print(d3.num)   # 输出 2
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

5.new&init

class Man:
    def __new__(cls, *args, **kwargs):
        print("new")
        # to do
        # 必须调用父类的new方法返回一个对象
        return super().__new__(cls)
    def __init__(self,age):
        print("init")
        self.age = age

man = Man(24)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12