类的主要组成部分:属性和方法 使用类可以创建出很多对象。只要是这个类创建出的对象都具有相关的属性和方法。但是这些对象又是相对独立的,每次创建出的对象是不同的个体。
#类的定义 class 类名: 属性 方法定义类时,类名后面可以加括号,可以不加括号,括号里面可以有object,可以没有object,object里面有很多有关类的属性和方法,在python3中会自动继承object的属性和方法。
#创建对象 对象 = 类名()创建对象时,如果给属性初始化默认值,就需要在括号内加入参数了
#对象调用属性和方法的方式: 对象.属性 对象.方法()先给出代码
class Demo: #定义属性 def __init__(self,a,b): self.a = a self.b = b #定义方法 def func1(self): print("类中的方法") demo1 = Demo(2,4) print(demo1.a,demo1.b) demo1.func1() #output 2 4 类中的方法使用__init__函数定义类的属性,可以在创建对象时就将属性绑定给对象,并且在__init__函数里面定义的变量在其它方法里面也能使用,这是对象的属性。 __init__函数的工作机制:在类创建对象时会自动调用__init__函数,然后使用__init__函数,将值传给对象,完成属性的初始化。
前面说到每个对象的属性是不同的,而这些属性是能够在方法中去呈现的。当对象实例去调用方法时,实例的属性是有差异的。所以在实例调用方法时,python首先会将该实例传给该方法,而self指的是这个实例,然后在执行函数里面的代码块。
class Demo: def __init__(self,a,b): self.a = a self.b = b def func1(self): print("类中的方法") def func2(self): print(self) demo1 = Demo(2,4) print(demo1) demo1.func2() #output <__main__.Demo object at 0x0000000002E3D278> <__main__.Demo object at 0x0000000002E3D278>小结:__init__函数能在创建对象时,完成对象属性的初始化。在调用方法时,会先将对象传入方法中,然后在执行函数内的代码块。
类变量:在类中,在方法以外定义的变量,是公有变量 实例变量:在方法中定义的变量 代码实现
class Demo: a = 12 #类变量 def __init__(self,b,c): self.b = b self.c = c def func1(self): print("这是一个比较类变量和实例变量的例子") #创建两个对象 demo1 = Demo(2,3) demo2 = Demo(4,5) #类变量是公有的 print("----------------------不同的对象访问类变量---------------------") print(demo1.a) print(demo2.a) #不同的实例对象有着不同的实例变量 print("-----------------不同的实例对象有着不同的实例变量---------------") print(demo1.b) print(demo2.b) #output ----------------------不同的对象访问类变量--------------------- 12 12 -----------------不同的实例对象有着不同的实例变量--------------- 2 4修改类变量的值
demo1.a = 13 print(demo1.a) #output 13小结:所有变量调用类变量(属性)的得到的值是一样的,不同对象的调用实例变量(属性)是有差异的。
如果想提高代码的安全性,使得变量不能直接被调用,可以在变量前加两个下划线。
class Demo: gong_you = 20 #类变量 def __init__(self,a,b,c): #实例变量 self.a = a self.b = b self.c = c def func1(self): print("定义的第一个函数") demo = Demo(1,2,3) print(demo.a) #调用类变量 print(demo.gong_you) #调用实例变量 #output 1 20将变量私有化
class Demo: gong_you = 20 #类变量 def __init__(self,a,b,c): #实例变量 self.__a = a #变量a私有化 self.b = b self.c = c def func1(self): print("定义的第一个函数") def getA(self): #创建得到__a的函数 return self.__a demo = Demo(1,2,3) print(demo.getA()) print(demo.gong_you) #调用实例变量 #output 1 20可以看到在变量前面加两个下划线后,说明这个变量你不能直接去调用它了,类似于被保护起来了,可以将它封装在函数中来使用它。对于类变量gong_you也是如此。
类是可以继承的,这也是为什么使用类的原因之一。当想要扩展代码时,可以减少代码的重复。
class Human: a = 12 def __init__(self,age,height): self.age = age self.height = height def learn(self): print("学习") class Students(Human): pass stu1 = Students(21,178) stu1.learn() print(stu1.a) #output 学习 12可以看到类Students继承了类Human的属性和方法,比如a,函数__init__(),,learn(),所以创建类Students的对象时,会自动调用类Human里面的__init__函数,需要传入年龄和身高的参数。 需要注意的是,如果在类Students里面重新定义__init__函数,则会将父类的__init__函数覆盖。如果没有会默认使用父类的__init__函数。
定义抽象类后,当在类中定义一个抽象方法,子类也必须有这个方法
import abc class Animals(metaclass=abc.ABCMeta): #定义抽象类 def __init__(self,name,color): self.name = name self.color = color #抽象方法 @abc.abstractmethod def eat(self):pass #无方法体,子类必须有eat()方法 class Cats(Animals): def eat(self): print("吃鱼") class Dogs(Animals): def eat(self): print("吃骨头") d = dogs("大黄","black")如果子类,没有eat()方法,则会有TypeError: Can’t instantiate abstract class Dogs with abstract methods eat的错误。需要注意的是抽象类不能创建实例。