属性
属性是指在类中定义的变量,根据变量在类中定义的位置,又可以分为类属性和实例属性。
类属性
类属性又称为静态属性,他是在类中的**方法(函数)**之外定义的属性,类属性既可以使用类名来调用,也可以使用对象来调用。类属性相当于类中的全局变量,可以被类中的所有方法使用。
类属性的调用方法:类名.类属性
,对象.类属性
。
实例属性
实例属性是在类的方法中定义的属性变量,实例属性只能通过类的对象来调用,不能通过类名字调用。
实例属性的调用方法:对象.实例属性
。
例如下面的country就是一个类属性,我们可以使用类名和类对象来调用它;__name,__age,sex是实例属性,我们只能通过对象来调用它:
class Person:
country = "china" # 定义一个类属性(静态属性)
def __init__(self, name, age, sex): # 这是一个方法,名字叫构造函数
self.__name = name # 实例属性
self.__age = age # 实例属性
self.sex = sex # 实例属性
def fun1(self): # 这是另外一个方法(函数)
print(self.__name)
print("使用类名调用类属性", Person.country) # ==> 使用类名调用类属性 china
tom = Person("tom", 20, "男”) # 实例化一个对象
print("使用对象调用类属性", tom.country) # ==> 使用对象调用类属性 china
print("使用对象调用实例属性", tom.sex) # ==> 使用对象调用实例属性 sex
类属性相当于类中的全局变量,可以被类中的所有方法使用
实例方法
实例方法的共同特点是至少具有一个参数,并且这个参数始终位于方法的参数中的第一个。习惯上使用self
表示。该参数的意义代表对象本身。
实例方法只能通过对象来调用,不能通过类名来调用.
class People:
def look(self):
print(id(self)) # 打印self的内存地址
tom = People()
print(id(tom)) # 打印对象tom的内存地址 ==>2907185294320
tom.look() # 调用look实例方法,查看self的内存地址 ==>2907185294320
通过上面的代码可以发现,对象tom和参数self的内存地址是一样的,这就说明self参数就是代表的对象本身.
实例方法可以使用类名.类成员
的方式访问类成员和属性.
类方法
类方法的表示方法是用一个@classmethod
修饰器修饰,并且类方法至少具有一个参数,该参数始终位于就类方法所有参数中的第一个,习惯上使用cls
表示,表示类本身.
类方法既能够通过类名来调用,也能够通过对象来调用.
class People:
@classmethod
def lookClass(cls):
print(id(cls)) # 打印cls的内存地址
tom = People() # 实例化一个对象
People.lookClass() # 通过类名来调用类方法 ==>2380734099872
tom.lookClass() # 通过对象来调用类方法 ==>2380734099872
print(id(People)) # 打印类的内存地址 ==>2380734099872
上面的代码的打印结果是cls的内存地址和类的内存地址是一样的,说明cls就代表类本身.
类方法不能访问实例成员,类方法能够使用类成员,方法是类名.类成员
,或者cls.类成员
.
静态方法
类的静态方法的表示方法是使用@staticmethod
修饰器修饰,静态方法不需要有必须的参数,参数可有可无.
静态方法不能访问实例对象,因为访问实例对象必须要有self
参数,静态方法不能使用cls
访问类成员,但是可以使用类名.类成员
访问类成员.
class People:
country = 'china'
def __init__(self, name, age):
self.name = name
self.age = age
@classmethod
def lookClass(cls):
print(id(cls)) # 打印cls的内存地址
@staticmethod
def lookStatic():
print('静态方法被调用')
tom = People('张胜男', 20) # 实例化一个对象
People.lookStatic() # 通过类名调用静态方法
tom.lookStatic() # 通过对象调用静态方法
print(id(tom)) # 打印对象的内存地址 ==>2099667687296
print(id(People)) # 打印类的内存地址 ==>2099669731360
print(id(People.lookStatic)) # 打印静态方法的内存地址 ==>2099671018816
上面的打印结果可以发现,静态方法的内存地址和类,对象的内存地址都不同,所以可以认为静态方法只是被封装到类中的第三方方法.