python3 类属性、实例属性、类方法、对象方法、静态方法

每次看到面向对象,我就看得有点头大,今天把这些都记下来,便于以后记忆。先放一段代码

class Person(object):
    # 限定Person对象只能绑定_name, _age和_gender属性
    __slots__ = ('_name', '_age', '_gender')
	count = 0
	
    def __init__(self, name, age):
        self._name = name
        self._age = age
        People.count += 1
	@classmethod
	def show_count(cls):
		print("总人数为%d" % cls.count)
	
    @property
    def name(self):
        return self._name

    @property
    def age(self):
        return self._age

    @age.setter
    def age(self, age):
        self._age = age

    def play(self):
        if self._age <= 16:
            print('%s正在玩飞行棋.' % self._name)
        else:
            print('%s正在玩斗地主.' % self._name)

def main():
    person = Person('王大锤', 22)
    person.play()
    person._gender = '男'
    # 类方法
    Person.show_count()
    # AttributeError: 'Person' object has no attribute '_is_gay'
    # person._is_gay = True

类属性和对象属性

首先,我们得明白一个道理,类也是一个特殊的对象(所以现有鸡还是先有蛋呢?可能得去看看对象的本质吧),类对象在内存中只有一份,使用一个类可以创建无数个对象实例。除了对象实例本身的属性和方法,每一个类对象也有自己本来的属性和方法
从上面这段代码我们可以看出
类属性:count
实例属性:name 、 age
这里插入一点,我们都知道python是动态语言,因此python里面,无论是类属性还是对象属性,都是可以临时添加的,虽然这样可以很灵活,但是有些时候我们也需要对其做一点限制。这就用到了__slot__ ,它可以限制People实例添加其余的属性。(不过我还没找到如何限制类属性,可能以后会在这里添加相关说明)

  • 如果使用 对象.类属性 = 值 ,这只会给对象新添加一个属性,不会影响到类属性的值。

类方法、对象方法、静态方法

除了常见的对象方法,类里面还有类方法和静态方法
类方法上面要加@classmethod 修饰器表示,而且与对象方法不同的是,类方法的第一个参数应该是cls(也可以是其他名字,不过规范来说是cls),在方法内部cls 可以调用其他类方法和类属性,它也可以调用构造函数去返回一个对象。

静态方法通常像是和这个类绑定的一个方法,但是它和类本身无关,静态函数上面需要加@staticmethod修饰器,它:

  • 既 不需要 访问 实例属性 或者调用 实例方法
  • 也 不需要 访问 类属性 或者调用 类方法

举个栗子:
构建一个三角形类,构造函数为它的三边,但是,我们实例化时需要判断这三条边能不能构建一个三角形,不能构建三角形就不将它实例化,因此这个判断函数就可以设置为一个静态函数。

from math import sqrt


class Triangle(object):
	__slot__ = ('a','b','c')
	Triangle_name = 'nb'
	def __init__(self, a, b, c):
		self._a = a
		self._b = b
		self._c = c

	# 静态方法
	@staticmethod
	def is_valid(a, b, c):
		return a + b > c and b + c > a and c + a > b

	# 实例方法
	def perimeter(self):
		return self._a + self._b + self._c

	# 实例方法
	def area(self):
		p = self.perimeter() / 2
		return sqrt(p * (p - self._a) * (p - self._b) * (p - self._c))


if __name__ == '__main__':
	# 用字符串的split方法将字符串拆分成一个列表
	# 再通过map函数对列表中的每个字符串进行映射处理成小数
	a, b, c = map(float, input('请输入三条边: ').split())
	# 先判断给定长度的三条边能否构成三角形
	# 如果能才创建三角形对象
	print(Triangle.Triangle_name)
	if Triangle.is_valid(a, b, c):
		tri = Triangle(a, b, c)
		print('周长:', tri.perimeter())
		print('面积:', tri.area())
		# 如果传入对象作为方法参数也可以通过类调用实例方法
		print('周长:', Triangle.perimeter(tri))
		print('面积:', Triangle.area(tri))
		# 看看下面的代码就知道其实二者本质上是一致的
		print(type(tri.perimeter))
		print(type(Triangle.perimeter))
	else:
		print('不能构成三角形.')
	Triangle.Triangle_no = 1
	print(Triangle.Triangle_no)

你可能感兴趣的:(python3 类属性、实例属性、类方法、对象方法、静态方法)