用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。
面向对象3要素:封装、继承、多态
1.类对象:类的定义就会生成一个类对象
2.类的属性:类定义中的变量和类中定义的方法都是类的属性
3.类变量
class Person:
x = "abc" #类属性
def __init__(self, name, age=18):#初始化函数,第一个位置必须是self。__init__方法不能有返回值,也就是只能是None
self.name = name
self.age = age
def showage(self): #类属性,也是方法,第一次参数必须是self(可以换名字,一般不要修改,影响代码可读性),这个参数位置留给了self
print("{} is {}".format(self.name, self.age))
a = Person("tom") #类实例化
b = Person("jerry", 20)
a.showage()
b.showage()
4.实例变量是每一个实例自己的变量,是自己独有的,类变量是类的变量,是类的所有实例共享的属性和方法
5.特殊属性
__name__ #对象名
__class__ #对象的类型
__dict__ #对象的属性的字典
__qualname__ #类的限定名
6.是类的,也就是这个类所有实例的,其实例都可以访问到,是实例的,就是这个实例自己的,通过类访问不到
类变量是属于类的变量,这个类的所有实例可以共享这个变量
实例可以动态的给自己增加一个属性。实例.__dict__[变量名]和实例.变量名都可以访问到
实例的同名变量会隐藏这类变量,或者说是覆盖了这个类变量
实例属性的查找顺序:
指的是实例使用.来访问属性,会先找自己的__dict__,如果没有,然后通过属性__class__找到自己的类,再去类的__dict__中找,注意:如果实例使用__dict__[变量名]访问变量,将不会按照上面的查找顺序找变量了。一般来说,类变量使用全大写来命名
class Person:
age = 3
height = 170
def __init__(self, name, age=18):
self.name = name
self.age = age
# def showage(self):
# print("{} is {}".format(self.name, self.age))
tom = Person("tom")
jerry = Person("jerry", 20)
Person.age = 30
print(Person.age, tom.age, jerry.age) #30 18 20
print(Person.height, tom.height, jerry.height) #170 170 170
Person.height += 20
print(Person.height, tom.height, jerry.height) #190 190 190
tom.height = 168
print(Person.height, tom.height, jerry.height) #190 168 190
jerry.height += 30
print(Person.height, tom.height, jerry.height) #190 168 220
7.装饰一个类
def setnameproperty(name):#通过装饰器,给MyClass动态增加一个NAME 属性
def wrapper(cls):
cls.NAME = name
return cls#必须返回cls
return wrapper
@setnameproperty("MY CLASS")
class MyClass:
pass
8.类方法
class Person:
@classmethod
def class_method(cls):
print("class = {0.__name__} ({0})".format(cls))
cls.HEIGHT = 170
Person.class_method()
print(Person.__dict__)
(1)使用@classmethod装饰器修饰的方法
(2)必须至少有一个参数,且第一个参数留给了cls,cls指代调用者即类对象自身
(3)cls这个标识符可以是任意合法名称,为了易读,不要修改
(4)通过cls可以直接操作类的属性
注意:无法通过cls操作类的实例。
9.静态方法
(1)在类定义中,使用@staticmethod装饰器修饰的方法
(2)调用时,不会隐式的传入参数
静态方法只是表明这个方法属于这个名词空间。函数归在一起,方便组织管理。用的相对较少
class Person:
@staticmethod
def static_method():
print(" ")
Person.static_method()
10.方法的调用
(1) 类几乎可以调用所有内部定义的方法,但是调用普通的方法时会报错,原因是第一个参数必须是类的实例。
(2)实例也几乎可以调用所有的方法,普通的函数的调用一般不可能出现,因为不允许如此定义
总结:(1)类除了普通方法都可以调用,普通方法需要对象的实例作为第一参数。
(2)实例可以调用所有类中定义的方法(包括类方法、静态方法),普通方法传入实例自身,静态方法和类方法需要找到实例的类。
11.访问控制
(1)私有(private)变量,使用双下划线开头的属性名。私有变量的本质:类定义的时候,如果声明一个实例变量的时候,使用双下划线,python解释器会将其改名,转换成名称为:_类名__变量名 的名称,所以用原来的名字访问不到了。
(2)保护变量,在变量名前使用一个下划线,称为保护变量。和普通属性一样,解释器不做任何特殊处理,这只是开发者共同的约定,看见这种变量,就如同私有变量,不要直接使用。
(3)私有方法,转换成名称为:_类名__方法名 的名称,所以用原来的名字访问不到了。类似私有变量。
私有成员总结:在python中使用_单下划线或者__双下划线来标识一个成员被保护或者被私有化隐藏起来。但是,不管使用什么样的访问控制,都不能真正的阻止用户修改类的成员。python中没有绝对的安全的保护成员或者私有成员。因此,前导的下划线只是一种警告或者提醒,请遵守这个约定。除非真的有必要,不要修改或者使用保护成员或者私有成员,更不要修改它们。