python其实也是一门面向对象语言,也有类 对象 的概念,也有继承的概念
创建类:
class ClassName:
'类的帮助信息' #类文档字符串
class_suite #类体:方法 变量等
构造函数:
def __init__(self):
可以有多个参数,创建类的实例后会自动调用该方法
实例化对象
对象=类名(参数)
如上面的t = Test()
访问类中成员
对象.成员 可以是成员函数也可以是类变量
t.pri()
print(t.count)
私有属性
__private:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问。在类内部的方法中使用时 self.__private
添加、删除,修改 属性
可以给对象添加属性、修改属性、删除属性:
class Test():
count = 0
def pri(s):
print(s)
print(s.__class__)
t = Test()
t1 = Test()
t.new = 10;
print(t.new)
#print(t1.new)
t.count = 1;
print('t.count',t.count)
print('t1.count',t1.count)
del t.new
输出结果为:
注意注释掉的那行,不注释会报错,因为对象t有属性new而对象t1并没有
也可以使用以下函数的方式来访问属性:
- getattr(obj, name[, default]) : 访问对象的属性。
- hasattr(obj,name) : 检查是否存在一个属性。
- setattr(obj,name,value) : 设置一个属性。如果属性不存在,会创建一个新属性。
- delattr(obj, name) : 删除属性。
内置类变量:
- __dict__ : 类的属性(包含一个字典,由类的数据属性组成)
- __doc__ :类的文档字符串
- __name__: 类名
- __module__: 类定义所在的模块(类的全名是'__main__.className',如果类位于一个导入模块mymod中,那么className.__module__ 等于 mymod)
- __bases__ : 类的所有父类构成元素(包含了一个由所有父类组成的元组)
class Test():
'this is doc'
def pri(self):
print('test!')
t=Test()
print(t.__doc__)
print(Test.__doc__)
print(Test.__name__)
类方法
类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称, 按照惯例它的名称是 self,self代表类的实例,而非类
class Test():
count = 0
def pri(s):
print(s)
print(s.__class__)
t = Test()
t.pri()
输出的结果如下:
<__main__.Test object at 0x0000000001F28828>
<class '__main__.Test'>
虽然有些IDE会自动补充self,但这并不是python关键字,将其替换成其他的也可以,比如s,一样可以执行
私有方法同样是以两个下划线开头:def __PrivateMethod():
下划线:
单下划线 双下划线 头尾下划线:
-
__foo__: 定义的是特殊方法,一般是系统定义名字 ,类似 __init__() 之类的。
-
_foo: 以单下划线开头的表示的是 protected 类型的变量,即保护类型只能允许其本身与子类进行访问,不能用于 from module import *
-
__foo: 双下划线的表示的是私有类型(private)的变量, 只能是允许这个类本身进行访问了
类的继承
class 子类名(基类名):- 1、在继承中基类的构造(__init__()方法)不会被自动调用,它需要在其派生类的构造中亲自专门调用。
- 2:在调用基类的方法时,需要加上基类的类名前缀,且需要带上self参数变量。区别在于类中调用普通函数时并不需要带上self参数
- 3:Python总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个查找。(先在本类中查找调用的方法,找不到才去基类中找)
- python支持多重继承,用,隔开
-
输出:class Parent(): def __init__(self): print('parent init') def method(self): print('parent method') attr = 0 def setAttr(self,att): attr = att; print(attr) class Child(Parent): def __init__(self): print('child init') def method(self): print('child method') c = Child() c.method() c.setAttr(5)
-
Child中有init函数,故没有调用父类的init(子类的覆盖了父类的函数,也是多态的特征);若没有时,则会调用父类的Init。子类重写了method()方法。子类可以没有构造函数,表示同父类的构造函数一致,也可以有自己的构造函数,也可以选择调用父类的构造函数 -
输出结果为:class Child(Parent): def __init__(self,a): Parent.__init__(self) a = 1 print(a) def method(self): print('child method') c = Child(5)
- parent init
1
- 对比java继承时的构造函数:
- “
- 如果父类不主动创建构造函数则子类创建构造函数没有限制。
- 如果父类创建不含参构造函数则子类创建构造函数没有限制且先执行父类的构造函数。
- 如果父类创建含参构造函数则子类创建构造函数需要先super父类函数且先执行父类的构造函数。
- 如果父类创建多个含参构造函数则子类创建构造函数需要先super指定的父类函数(如父类包含无参构造函数则子类可以不super父类函数同测试2)。
- Python多重继承时,优先用层级靠近的类中的方法
- issubclass() - 布尔函数判断一个类是另一个类的子类或者子孙类,语法:issubclass(sub,sup)
- isinstance(obj, Class) 布尔函数如果obj是Class类的实例对象或者是一个Class子类的实例对象则返回true。
- 运算符重载
- python支持运算符重载:
-
class Parent(): def __init__(self,a,b): self.a =a self.b = b def __add__(self, other): return (self.a+other.a ,self.b+other.b) def __sub__(self, other): return (self.a - other.a, self.b - other.b) p = Parent(1,2) t = Parent(3,-4) print(p-t)#输出(-2,6)
-
-