1.类是什么?
类是用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。
对象是类的是类。
类是抽象的模板,而实例是根据类创建出来的一个个具体对象,每个对象拥有相同的方法,各个实例拥有的数据都互相独立,互不影响
方法就是与实例绑定的函数,和普通函数不同,方法可以直接访问实例的数据。
2. 类的一般形式
创建类
使用class 来创建一个新类,class之后为类的名词并以冒号结尾:
class ClassName: '类的帮助信息' #类文档字符串 class_suite #类体
例如:
class ren(object): ''' this is a class ''' name='yany' sex='f' a=ren() print(type(a)) print(a.name) print(a.sex) a.sex='m' print (a.sex)
<class '__main__.ren'> yany f m
解释:
1. object默认是所有类的父类,不写默认继承object
2. a = ren(),就是把类ren实例化,
3. 以上打印a的类型就是一个ren的类
4. 调用类的方法和变量,直接实例化类的后面直接用“.”调用就可以。如果想给实例a添加变量或者赋值,可以直接用“.”加变量赋值。
3.类的构造器
__init__()方法是一种特殊的方法,被称为类的构造函数或初始化方法,当创建了这个类的实例时就会调用该方法
__init__构造函数,在生成对象时调用。由于类可以起到模板的作用,因此,可以在创建实例的时候,把一些我们认为必须绑定的属性强制填写进去。通过定义一个特殊的__init__方法,在创建实例的时候,就把name,score等属性绑上去
class student(object): def __init__(self,name,score): self.name=name self.score=score
注意到__init__方法的第一个参数永远是self,表示创建的实例本身,因此,在__init__方法内部,就可以把各种属性绑定到self,因为self就指向创建的实例本身。
__init__方法,在创建实例的时候,就不能传入空的参数了,必须传入与__init__方法匹配的参数,但self不需要传,Python解释器自己会把实例变量传进去:
class student(object): def __init__(self,name,score): self.name=name self.score=score s=student('yyag',89) print(s.name) print(s.score)
解释:
1,在传递参数的时候,必须是传递两个参数,name和score,不然报错
2,Self的参数不用传递,python自动会把Student实例化的s传递给第一个参数,即self
注意:特殊方法“ init ”前后有两个下划线!!!
4.类的继承
即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,你现在有一个现有的A类,现在需要写一个B类,但是B类是A类的特殊版,我们就可以使用继承,B类继承A类时,B类会自动获得A类的所有属性和方法,A类称为父类,B类陈为子类,子类除了继承父类的所有属性和方法,还可以自定义自己的属性和方法,大大增加了代码的复用性。
面向对象的编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是通过继承机制。继承完全可以理解成类之间的类型和子类型关系。
需要注意的地方:继承语法 class 派生类名(基类名)://... 基类名写在括号里,基本类是在类定义的时候,在元组之中指明的。
在python中继承中的一些特点:
1:在继承中基类的构造(__init__()方法)不会被自动调用,它需要在其派生类的构造中亲自专门调用。
2:在调用基类的方法时,需要加上基类的类名前缀,且需要带上self参数变量。区别在于类中调用普通函数时并不需要带上self参数
3:Python总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个查找。(先在本类中查找调用的方法,找不到才去基类中找)。
4:Python总是首先子类中的方法,如果子类没有找到,才回去父类中查找。
如果在继承元组中列了一个以上的类,那么它就被称作"多重继承" 。::.
语法:
派生类的声明,与他们的父类类似,继承的基类列表跟在类名之后,如下所示:
多继承其实在需要在父类的位置,直接写多个父类就可以,然后用“,”分开就可以了,C类就同时继承了A类和B类class A(父类):
…
Python的类支持多继承,而java没有多继承,但是可以有多接口的实现python的多继承很简单,下面我们来看一下多继承的格式:
class A: # 定义类 A
.....
class B: # 定义类 B
.....
class C(A,B): # 继承类 A 和 B
举例:
class parent(): name='parent' age=100 def __init__(self): print("my name is parent") def get_name(self): return self.name def get_age(self): return self.age class child(parent): def __init__(self): print('my name is child') def hello(self): print('hello child') a=child() a.hello() print(a.get_name()) print(a.get_age())结果:
my name is child hello child parent 100
如果子类没有定义__init__()方法,子类初始化的时候就会调用父类的方法,但是当子类定义了__init__()方法,子类就不会调用父类的__init__()方法,那如果子类想实现父类构造器中的方法,然后自己在写自己特殊的方法呢,这样该怎么办呢?
super(object) class parent(object): name='parent' age=100 def __init__(self): print("my name is parent") def get_name(self): return self.name def get_age(self): return self.age class child(parent): def __init__(self): super(child,self).__init__() print('my name is child') def hello(self): print('hello child') a=child() a.hello() print(a.get_name()) print(a.get_age())
my name is parent my name is child hello child parent 100
这时候就出现了子类调用父类的__init__()的方法,
注意:
这里在class parent(object):定义父类的时候,一定要写继承object类,不然那就会有如下的报错信息:TypeError: super() argument 1 must be type, notclassobj,增加parent(object)就可以轻松解决。
方法的重写
如果父类的方法的功能不能满足需求,可以砸子类重写父类的方法:
super(object) class parent(object): name='baba' age=56 def __init__(self): print('my bab is bab') def get_name(self): return self.name def get_age(self): return self.age class child(parent): def __init__(self): super(child,self).__init__() print('i is my babs doug') def hello(self): print ('hello!!!!') a=child() a.hello() print(a.get_name()) print(a.get_age())
my bab is bab
i is my babs doug
hello!!!!
baba
56
对继承父类中的方法,在添加父类方法,需要使用super。
class parent(object): def __init__(self): print "star******" def get_name(self): print "my baba is mine" def get_sex(self): print"is f" class child(parent): def __init__(self): print"child start%%%%%%%%" def get_name(self): super(child,self).get_name() print"i am is a child" a=child() a.get_name()结果:
child start%%%%%%%% my baba is mine i am is a child
基础重载的方法:
序号 | 方法, 描述 & 简单的调用 |
---|---|
1 | __init__ ( self [,args...] ) 构造函数 简单的调用方法: obj = className(args) |
2 | __del__( self ) 析构方法, 删除一个对象 简单的调用方法 : del obj |
3 | __repr__( self ) 转化为供解释器读取的形式 简单的调用方法 : repr(obj) |
4 | __str__( self ) 用于将值转化为适于人阅读的形式 简单的调用方法 : str(obj) |
5 | __cmp__ ( self, x ) 对象比较 简单的调用方法 : cmp(obj, x) |
私有变量和私有方法:
在Python中可以通过在属性变量名前加上双下划线定义属性为私有属性
类的私有属性
__private_attrs:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问。在类内部的方法中使用时 self.__private_attrs。
类的方法
在类的内部,使用 def 关键字可以为类定义一个方法,与一般函数定义不同,类方法必须包含参数 self,且为第一个参数
类的私有方法
__private_method:两个下划线开头,声明该方法为私有方法,不能在类地外部调用。在类的内部调用 self.__private_methods
特殊变量命名
1、 _xx 以单下划线开头的表示的是protected类型的变量。即保护类型只能允许其本身与子类进行访问。若内部变量标示,如: 当使用“from Mimport”时,不会将以一个下划线开头的对象引入 。
2、 __xx 双下划线的表示的是私有类型的变量。只能允许这个类本身进行访问了,连子类也不可以用于命名一个类属性(类变量),调用时名字被改变(在类FooBar内部,__boo变成_FooBar__boo,如self._FooBar__boo)
3、 __xx__定义的是特列方法。用户控制的命名空间内的变量或是属性,如init , __import__或是file 。只有当文档有说明时使用,不要自己定义这类变量。 (就是说这些是python内部定义的变量名)
在这里强调说一下私有变量,python默认的成员函数和成员变量都是公开的,没有像其他类似语言的public,private等关键字修饰.但是可以在变量前面加上两个下划线"_",这样的话函数或变量就变成私有的.这是python的私有变量轧压(这个翻译好拗口),英文是(private name mangling.) **情况就是当变量被标记为私有后,在变量的前端插入类名,再类名前添加一个下划线"_",即形成了_ClassName__变量名.**
举例说明:
class a(object): _name='yyang' __sex='f' def hello(self): print(self._name) print(self.__sex) def get_sex(self): return self.__sex b=a() print(b._name) # print(b.__sex)//实例后,不能访问__sex私有成员,实例不能访问。 print (b.get_sex())
b.hello()结果:
yyang f yyang f从以上可以可出:
_xx,是受保护的变量,只允许本身和子类进行访问,属于内部变量
__xx,类中访问。
Python内置类属性
__dict__ : 类的属性(包含一个字典,由类的数据属性组成)
__doc__ :类的文档字符串
__module__: 类定义所在的模块(类的全名是'__main__.className',如果类位于一个导入模块mymod中,那么className.__module__等于 mymod)
__bases__ : 类的所有父类构成元素(包含了一个由所有父类组成的元组)
yyang f yyang f