面向对象
类属性和实例属性的操作
-
如何获取类属性、修改类属性、非常规手段访问私有类属性?
-
注意
- 对象不能修改类属性,但是对象可以获取类属性;
- 不能使用类来访问和修改实例属性,实例属性的操作都是有实例或者对象来完成的;
-
即:对象可以调用对象和类的,类只能调用类的;
- 修改的话只能自己改自己的(对象顶多调用
__class__
来改类属性,但本质还是类改类的)。
- 修改的话只能自己改自己的(对象顶多调用
-
扩展:获取对象的类—
对象.__class__
,返回<class '__main__.类名'>
class Person(object):
# 公有的类属性
country = "中国"
# 私有的类属性,在外界不能访问,只能在类内部使用
__color = "黄种人"
def __init__(self):
# 在init方法里面定义的属性称为实例属性或者对象属性
self.name = "李四"
self.__age = 18
def show(self):
pass
# --------------类属性的操作--------------
# 获取类属性
print(Person.country)
# 查看类属性信息
print(Person.__dict__)
# 非常规手段访问私有的类属性
print(Person._Person__color)
# 修改类属性,注意点:必须使用类来完成,不能使用对象
Person.country = "美国"
print(Person.__dict__)
# 创建Person类的对象
p = Person()
# 查看实例属性信息
print("p对象的属性信息:", p.__dict__)
# 本意是要修改类属性,其实是完成一个对象属性的添加
p.country = "日本"
print(Person.country) # 类属性并未变成“日本”
print("查看类属性", Person.__dict__)
print("P对象的属性信息:", p.__dict__)
# 注意点: 对象不能修改类属性,但是对象可以获取类属性
print(p.country)
# 扩展:获取对象的指定类
print('获取对象的类', p.__class__)
# 先通过对象获取对应的类,然后通过类获取类属性
print(p.__class__.country)
# 先获取对象的所对应的类,然后通过类修改类属性
p.__class__.country = "日本"
print(Person.__dict__)
# --------------实例(对象)属性的操作--------------
# 略,无非通过“对象.属性”来获取和修改
# 不能使用类来访问和修改实例属性,实例属性的操作都是有实例或者对象来完成的
# 本意是要修改实例属性,其实是对类添加的一个类属性
Person.name = "冯七"
print('类属性的信息:', Person.__dict__)
实例方法、类方法、静态方法
- 总结:类和对象都可调用这三种方法,但是注意点不一样。
- 实例方法:在类中方法的第一个参数是
self
,self
表示当前对象,那么这样定义的方法就是实例(对象)方法。- 对象和类都可以调用实例方法,但是类调用对象方法需要手动传入
self
对应的当前对象,写法:类.对象方法(对象)
- 对象和类都可以调用实例方法,但是类调用对象方法需要手动传入
class Lei(object):
def object_def(self):
pass
- 类方法:方法的第一个参数是
cls
,并且在方法上面加上一个@classmethod
关键字,cls
表示当前类,那么这样定义的方法就是类方法。- 类方法只能修改类属性,不能修改对象属性,因为没有传入当前对象
self
,可以自己传入。 - 类和对象都可以调用类方法,对象调用类方法,简写:
对象.类方法()
;完整写法:对象.__class__.类方法()
。
- 类方法只能修改类属性,不能修改对象属性,因为没有传入当前对象
class Lei(object):
@classmethod
def lei_def(cls): # cls表示当前类
pass
- 静态方法:方法的参数没有
self
和cls
并且方法上面加上一个@staicmehthod
关键字,静态方法不需要使用当前对象和当前类。- 以后开发使用实例方法比较多,如果定义的方法不需要使用当前对象和当前类,那么可以定义成静态方法。
- 类和对象都可以调用静态方法,直接调用就行。
class Lei(object):
@staticemethod
def statice_def():
pass
- 案例很详
class Person(object):
# 私有的类属性
__country = "中国"
def __init__(self, name, age):
self.name = name
# 私有的实例属性
self.__age = age
# 定义实例(对象)方法,应用场景,可以修改私有实例属性和获取私有实例属性
def set_age(self, new_age):
if (new_age >= 0) and (new_age <= 150):
self.__age = new_age
# 定义实例(对象)方法
def get_age(self):
return self.__age
# 定义实例(对象)方法
def set_country(self, new_country):
# 扩展: 实例方法可以通过对象间接修改类属性
self.__class__.__country = new_country
def get_country(self):
# 获取类属性, 1. 使用对象获取类属性 2. 使用类获取类属性
# return self.__country
# return Person.__country
# 这样写代码更加通用,类属性还是通过类来完成的
return self.__class__.__country
# 定义类方法,类方法只能修改类属性,不能修改对象属性
@classmethod
def modify_country(cls, new_country): # cls表示当前类
cls.__country = new_country
# 定义静态方法
@staticmethod
def sum_num(num1, num2):
return num1 + num2
p = Person("李四", 20)
# 实例方法的使用
p.set_age(120)
print(p.get_age())
# 通过对象函数设置类属性
p.set_country("美国")
print(p.get_country())
# 通过类调用类方法
Person.modify_country("日本")
print(p.get_country())
# 通过对象调用类方法
# 对应类方法来说,可以使用对象进行调用,并且当前类这个参数不需要程序员手动去传
p.modify_country("中国1")
print(p.get_country())
# 扩展: 完整写法
p.__class__.modify_country("中国2")
print(p.get_country())
# 类去调用实例方法的时候,self参数需要手动自己去传, 不建议这样去写,比较麻烦
age = Person.get_age(p)
print(age)
# 静态方法的调用,可以使用类和对象来进行调用
result = p.sum_num(1, 2)
print(result)
result = Person.sum_num(1, 2)
print(result)