1、什么是类对象,实例对象
类对象:类名
实例对象:类创建的对象
2、类属性就是类对象
所拥有的属性,它被所有类对象
的实例对象
所共有,在内存中只存在一个副本,这个和C++、Java中类的静态成员变量有点类似。对于公有的类属性,在类外可以通过类对象
和实例对象
访问
类属性
[java] view plain copy
1. # 类属性
2. class people:
3. "Tom" #公有的类属性
4. 18 #私有的类属性
5.
6. p=people()
7. print(p.name) #实例对象
8. print(people.name) #类对象
9.
10. # print(p.__age) #错误 不能在类外通过实例对象访问私有的类属性
11. print(people.__age) #错误 不能在类外同过类对象访问私有的类属性
实例属性
[java] view plain copy
1. class people:
2. "tom"
3.
4. p=people()
5. p.age=18
6.
7. print(p.name)
8. print(p.age) #实例属性是实例对象特有的,类对象不能拥有
9.
10. print(people.name)
11. #print(people.age) #错误:实例属性,不能通过类对象调用
也可以将实例属性放在构造方法中
[java] view plain copy
1. class people:
2. "tom"
3. def __init__(self,age):
4. self.age=age
5.
6. p=people(18)
7.
8. print(p.name)
9. print(p.age) #实例属性是实例对象特有的,类对象不能拥有
10.
11. print(people.name)
12. # print(people.age) #错误:实例属性,不能通过类对象调用
类属性和实例属性混合
[java] view plain copy
1. class people:
2. "tom" #类属性:实例对象和类对象可以同时调用
3. def __init__(self,age): #实例属性
4. self.age=age
5.
6. p=people(18) #实例对象
7. p.sex="男" #实例属性
8.
9. print(p.name)
10. print(p.age) #实例属性是实例对象特有的,类对象不能拥有
11. print(p.sex)
12.
13. print(people.name) #类对象
14. # print(people.age) #错误:实例属性,不能通过类对象调用
15. # print(people.sex) #错误:实例属性,不能通过类对象调用
# 如果在类外修改类属性,必须通过类对象去引用然后进行修改。如果通过实例对象去引用,
# 会产生一个同名的实例属性,这种方式修改的是实例属性,不会影响到类属性,并且如果通过
# 实例对象引用该名称的属性,实例属性会强制屏蔽掉类属性,即引用的是实例属性,除非删除了该实例属性
[java] view plain copy
1. class Animal:
2. "Panda"
3.
4. print(Animal.name) #类对象引用类属性
5. p=Animal()
6. print(p.name) #实例对象引用类属性时,会产生一个同名的实例属性
7. p.name="dog" #修改的只是实例属性的,不会影响到类属性
8. print(p.name) #dog
9. print(Animal.name) #panda
10.
11. # 删除实例属性
12. del p.name
13. print(p.name)
[java] view plain copy
1. class Test:
2.
3. 100 #类属性
4. def __init__(self):
5. 18 #实例属性
6.
7. test1=Test()
8. test2=Test()
9. # test1.age=19
10. # test2.age=20
11. print(test1.num) #100
12. test1.num=200 #如果通过对象去修改类属性,那么Python会自动给这个对象和这个类属性相同名字的实例属性
13. print(test1.num) #200,只是修改了副本
14. print(Test.num) #100
15.
16. del test1.num #删除之后,仍能打印
17. print(test1.num)
3、类方法
是类对象所拥有的方法,需要用修饰器@classmethod
来标识其为类方法,对于类方法,第一个参数必须是类对象,一般以cls
作为第一个参数(当然可以用其他名称的变量作为其第一个参数,但是大部分人都习惯以'cls'作为第一个参数的名字,就最好用'cls'了),能够通过实例对象和类对象去访问。
[java] view plain copy
1. class people:
2. "china"
3.
4. @classmethod
5. def getCountry(cls):
6. return cls.country
7.
8. p=people()
9. print(p.getCountry()) #实例对象调用类方法
10. print(people.getCountry()) #类对象调用类方法
类方法还有一个用途就是可以对类属性进行修改:
[java] view plain copy
1. class people:
2. "china"
3.
4. @classmethod
5. def getCountry(cls):
6. return cls.country
7. @classmethod
8. def setCountry(cls,country):
9. cls.country=country
10.
11.
12. p=people()
13. print(p.getCountry()) #实例对象调用类方法
14. print(people.getCountry()) #类对象调用类方法
15.
16. p.setCountry("Japan")
17.
18. print(p.getCountry())
19. print(people.getCountry())
4、静态方法
需要通过修饰器@staticmethod
来进行修饰,静态方法不需要多定义参数
[java] view plain copy
1. class people3:
2. "china"
3.
4. @staticmethod
5. def getCountry():
6. return people3.country
7.
8. p=people3()
9. print(p.getCountry()) #实例对象调用类方法
10. print(people3.getCountry()) #类对象调用类方法
从类方法和实例方法以及静态方法的定义形式就可以看出来,类方法的第一个参数是类对象cls,那么通过cls引用的必定是类对象的属性和方法;而实例方法的第一个参数是实例对象self,那么通过self引用的可能是类属性、也有可能是实例属性(这个需要具体分析),不过在存在相同名称的类属性和实例属性的情况下,实例属性优先级更高。
静态方法中不需要额外定义参数,因此在静态方法中引用类属性的话,必须通过类对象来引用