python学习日记13(类和属性)
类属性和对象属性
类属性、实例属性
实例属性
通过类创建的对象被称为实例对象,对象属性也称为实例属性,记录对象各自的数据,不同对象的同名属性的数据保存在各自的内存区域,互不干扰。
类属性
类属性是类对象所拥有的属性,它被该类所创建的实例对象所共有,类属性可以通过类对象或者实例对象访问。
使用场景:
- 类的实例记录的某项数据始终保持一致时,则定义为类的属性
- 实例属性要求每个对象都开辟一份单独内存来存储数据;而类属性为类的实例所共有,仅占用类区域内的一份内存。
注意事项:
- 尽量避免类属性和实例属性同名,如果存在同名,实例对象会优先访问实例属性。
- 类属性只能通过类对象进行修改,不能通过实例对象修改。
- 类属性也可设置为私有。
私有属性和方法
在实际开发过程中,对象的某些属性或者方法可能只希望在对象的内部进行使用,而不希望类外部被访问到,这是就可以定义私有属性和私有方法。
私有属性或方法的定义
在定义类的属性或者方法时,在属性名或者方法名前增加两个下划线__
,定义的属性或者方法就是私有属性或方法。
class Person:
def __init__(self,name,age):
self.name = name
self.age = age
self.__money = 2000 # 使用 __ 修饰的属性,是私有属性
def __shopping(self, cost):
self.__money -= cost # __money 只能在对象内部使用
print('还剩下%d元'%self.__money)
def test(self):
self.__shopping(200) # __shopping 方法也只能在对象内部使用
p = Person('张三',18)
# print(p.__money) 这里会报错,不能直接访问对象内部的私有属性
p.test()
# p.__shopping() 这里会报错,__shopping 只能在对象内部使用,外部无法访问
访问私有属性或方法
私有属性不能被直接使用,私有方法也不能被直接调用,但是,通过操作我们还是可以从外部访问到。
- 直接访问
class Person:
def __init__(self,name,age):
self.name = name
self.age = age
self.__money = 2000
def __shopping(self, cost):
self.__money -= cost
p = Person('李四',20)
print(p._Person__money) # 使用对象名._类名__私有属性名 可以直接访问对象的私有属性
p._Person__shopping(100) # 使用对象名._类名__函数名 可以直接调用对象的私有方法
print(p._Person__money)
注意:强烈不建议使用对象名._类名__私有属性名
的方法来访问对象的私有属性!
- 定义方法访问
如果想要修改私有属性,可以使用get
和set
方法这种方式来实现。
class Person:
def __init__(self,name,age):
self.name = name
self.age = age
self.__money = 2000 # __money 是私有变量,外部无法访问
def get_money(self): # 定义了get_money 方法,在这个方法里获取到 __money
return self.__money # 内部可以访问 __money 变量
def set_money(self,money): # 定义了set_money 方法,在这个方法里,可以修改 __money
self.__money = money
p = Person('王五',21)
# 外部通过调用 get_money 和 set_money 这两个公开方法获取和修改私有变量
print(p.get_money())
p.set_money(8000)
print(p.get_money())
类方法和静态方法
类方法
- 类方法的第一个形参是类对象的方法
cls
- 需要装饰器
@classmethod
来表示其为类方法
class Dog(object):
__type = "狗"
# 类方法,用classmethod来进行修饰
@classmethod
def get_type(cls):
return cls.__type
print(Dog.get_type())
使用场景:
- 当方法中需要使用类对象(如访问私有类属性等)时,定义类方法方便使用。
- 类方法一般和类属性配合使用
静态方法
静态方法需要使用@staticmethod
装饰器进行修饰,静态方法既不需要传递参数也不需要传递实例对象(形参中也不需要添加self或cls)
静态方法 也能通过实例对象和类对象去访问
class Dog(object):
type = "狗"
def __init__(self):
name = None
# 静态方法
@staticmethod
def introduce(): # 静态方法不会自动传递实例对象和类对象
print("犬科哺乳动物,属于食肉目..")
dog1 = Dog()
Dog.introduce() # 可以用 实例对象 来调用 静态方法
dog1.introduce() # 可以用 类对象 来调用 静态方法