1.说明
类(class):是用来描述具有相同属性和方法的对象的集合。他定义了该集合中每个对象所共有的属性和方法。
方法:类中定义的函数。
类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。
对象:根据类定义的结构进行的引用。
实例化:指对类的调用,因为类是一种相同属性和方法的集合,因此在程序中可能有多次引用这个集合,引用的操作就是实例化。
2.示例
2.1类的定义
#!/usr/bin/python3
#定义一个类
class MyClass:
i = 12345 #定义类的属性i
def f(self): #定义类的方法f
return 'hello world'
2.2类的实例化、属性、方法
#实例化类
X = MyClass()
#访问类的属性
X.i
#访问类的方法
X.f()
# X.i输出12345
# X.f()输出hello world
总的来说,类的作为一种规定了相似属性和方法的集合,可以在程序中多次调用,这种对类的调用称之为类的实例化。
在写类的时候,类中的变量称之为属性;类中的子函数称之为方法,可以理解一下。
2.3类的__init__方法
在很多工程中,会经常看到一个类中定义了一个__init__()的函数,这是类中的一个特殊方法,在实例化的时候会自动调用,型如下:
def __init__(self):
self.data = []
__init__()方法可以有参数,参数通过该方法传递到实例化的操作上。
#!/usr/bin/python3
class Complex:
def __init__(self, realpart, imagpart):
self.r = realpart
self.i = imagpart
x = Complex(3.0, -4.5)
print(x.r, x.i) # 输出结果:3.0 -4.5
有的时候会犯迷糊self到底是什么,为什么占了一个变量的位置但是在实例化传递参数的时候却没有传递给self参数,反而按顺序看的话会把参数传递给后面的变量。这里是因为self作为本身类class实例化的名字,在__init__里用self来代表类名。__init__中规定了类名+.x的赋值情况,因此在self后面的两个变量才是真正用到或者说在实例化中需要传递参数的变量。self只作为类名的替代。
2.4类的方法
这一部分说明了__xxxx在类中如果作为属性的话是一种名为”私有属性“的写法,在外部是无法直接访问的会报错。如果用到的话再仔细看一下。
#!/usr/bin/python3
class father:
name = ''
gender = ''
age = 0
__weight = 0
def __init__(self , name , gender , age ,weight):
self.name = name
self.gender = gender
self.age = age
self.__weight = weight
def speak(self):
print("%s说我是一个%s,我今年%d岁,我%d公斤" %(self.name,self.gender,self.age,self.weight))
x = father('awei','man',25,30)
x.speak()
#输出 报错
'''
Traceback (most recent call last):
File "/root/Python_01/main.py", line 18, in <module>
x.speak()
File "/root/Python_01/main.py", line 15, in speak
print("%s说我是一个%s,我今年%d岁,我%d公斤" %(self.name,self.gender,self.age,self.weight))
AttributeError: 'father' object has no attribute 'weight'
'''
#说明__weight无法在外部进行访问
#!/usr/bin/python3
class father:
name = ''
gender = ''
age = 0
weight = 0
def __init__(self , name , gender , age ,weight):
self.name = name
self.gender = gender
self.age = age
self.weight = weight
def speak(self):
print("%s说我是一个%s,我今年%d岁,我%d公斤" %(self.name,self.gender,self.age,self.weight))
x = father('awei','man',25,30)
x.speak()
'''
awei说我是一个man,我今年25岁,我30公斤
'''
'''
这里说明一下def __init__(self , name , gender , age ,weight):这其中的变量即便是重复也无所谓,作为形参使用。
'''
2.5继承
继承和派生是当初学C++时候经常听到老师提到的两个词,但是当时并没有好好理解。
python中的基本形式如下:
class DerivedClassName(BaseClassName):
<statement-1>
.
.
.
<statement-N>
这里的子类或者叫做派生类是DerivedClassName,他所继承的父类名称为BaseClassName,啰嗦一点说,这样的基本写法就构成了继承关系,BaseClassName作为父类有他本身的属性和方法,在这里DerivedClassName作为派生类就继承了BaseClassName父类的属性和方法。
#!/usr/bin/python3
class father:
name = ''
gender = ''
age = 0
weight = 0
'''
定义构造方法
'''
def __init__(self , name , gender , age ,weight):
self.name = name
self.gender = gender
self.age = age
self.weight = weight
def speak(self):
print("%s说我是一个%s,我今年%d岁,我%d公斤" %(self.name,self.gender,self.age,self.weight))
class son(father):
height = ''
def __init__(self ,name ,gender ,age ,weight ,height ):
'''
调用父类构函
'''
father.__init__(self , name , gender , age ,weight)
self.height = height
def speak(self):
print("%s说我是一个%s,我今年%d岁,我%d公斤,%s高。" %(self.name,self.gender,self.age,self.weight,self.height))
X = son('awei' , 'man' , 25 , 100 , 150)
X.speak()
关于继承的写法如上所示,对于父类来说并没有什么变化,对于派生类,首先在定义类名之后的括号中要写明继承的父类名称。·其次在派生类的初始化方法中要对父类进行构函操作。
实例化时,对于派生类的参数传递数目参照的时派生类中初始化方法中除self之外的参数个数和位置。
2.6多继承
多继承就是在派生类的类名括号里包含了多个父类,,用法与普通继承相同,但是有一点需要注意,当有多个父类继承的时候,如果父类中有相同的方法名,默认按照自左向右的顺序调用父类的方法。给出以下示例:
#!/usr/bin/python3
class father1:
name = ''
age = 0
def __init__(self , name , age):
self.name = name
self.age = age
def speak(self):
print("%s说我%d岁了"%(self.name , self.age))
class father2:
job = ''
def __init__(self , name , age ,job):
father1.__init__(self , name , age)
self.job = job
def speak(self):
print("%s说我%d岁了,我的工作是%s."%(self.name , self.age , self.job))
class son(father2 , father1):
def __init__(self , name , age ,job):
father2.__init__(self , name , age ,job)
father1.__init__(self , name , age)
X = son('awei' , 25 , 'student')
X.speak()
'''
awei说我25岁了,我的工作是student.
'''
在派生类son中这里是father2在前面,因为father1和father2都使用了相同名称的方法,因此根据自左向右调用方法的原则,输出的结果格式是按照父类1进行输出的,如果更改派生类后面father1和2的顺序,结果也会随之改变。
2.7超类
当父类方法不能满足你的需求,可以使用super()函数进行超类。
#!/usr/bin/python3
class Parent: # 定义父类
def myMethod(self):
print ('调用父类方法')
class Child(Parent): # 定义子类
def myMethod(self):
print ('调用子类方法')
c = Child() # 子类实例
c.myMethod() # 子类调用重写方法
super(Child,c).myMethod() #用子类对象调用父类已被覆盖的方法
'''
调用子类方法
调用父类方法
'''
super((子类名,子类示例变量名).子类方法名)