python(类详解)

面向对象,面向过程的区别:
面向过程开发,以函数作为基本结构使用:
面向对象的开发,以对象作为基本结构使用
语言中对象结构的特色:高内聚,低耦合。
类的定义
类是一个实物的特征的集合,是抽象的概念。
类和对象的关系 类是多个对象归纳总结而来的,是一种概念,包含所有对象。

由对象总结出类的过程,叫做抽象化 对象是类的具体实现或者实施而来,他是真实的,特指某个事物
由类制作出对象的过程,叫做实例化 如何书写类文件 推荐使用驼峰命名法来书写文件
定义规则:
类名:每个单词的首字母大写
函数名 /变量:除了第一个单词之外首字母大写
类的组成:
一个文件如果是一个单独的类,那么直接使用类名来当作文件名即可
类的组成 类中只有2种内容:成员属性和成员方法
成员属性: 用于描述类的特征的变量就是成员属性
成员方法: 用于描述类的功能的函数就是成员方法
类的书写规则 1.必须使用class关键字来声明一个类
2.类的名称需要符合驼峰命名法(规范)
3.类中只能存在2种内容,成员属性和成员方法,除此之外,所有的代码都禁止出现!
4.声明成员属性时,所有成员属性必须有值,如果没值会报错!,推荐使用None等值代替
5.成员方法只需要按照函数的规则声明即可实例化对象 实例化对象格式
注意:在定义类的成员方法的时候,方法的参数至少有一个self。相当于c++中的this指针
class A():
def fun():
print(“我和石头做游戏”)
编译报错:
File “E:/project/作业_20180821.py”, line 199
path = “D:\”"
^
SyntaxError: EOL while scanning string literal

init(self):python中的构造方法
除类self之外,还可以传入其他参数。通过重写方法制定这些初始化操作

私有,公有
私有: 在变量和函数名前加上两个下划线(__)就可以类
注意:私有变量在类外不能进行访问和修改,只能通过内部访问和修改(调用get,set函数)

继承 lass 子类(父类) :
#继承操作的关键步骤 pass 继承的特征
1.所有类都是继承自object类(object类对应的对象就是object对象,也是万物皆对象)
2.子类继承父类则可以访问父类的所有成员。(私有成员除外)
3.子类继承父类并不会将父类的所有成员复制到子类当中去,访问父类成员是间接通过父类来访问的,
4.子类可以具有自己独有的属性和方法
5.子类可以重载父类中的方法,只需要设置和父类指定成员相同的名称即可实现重载,重载之后的成员,子类只会访问当前类中的成员,而不会调用父类中同名的成员
6.子类中如果重载父类的方法,并且还想将重载的父类方法借调过来使用,可以在重载的方法中使用如下方法 父类名.方法()或者 super().方法() 单继承和多继承 单继承:每个类只能继承一个类的方式称为单继承。
7.父类中的私有化方法和属性不能被继承
父类名.方法(self) :调用未绑定的父类方法
格式:父类名.方法(self)
注意:当使用这种方法调用父类的方法时候,父类的方法的参数是子类的实例化对象
super(). :使用super()函数
格式:super().父类名.方法()
注意:这里不需要将自对象的实例化参数self传入
注意:对于你定义的每一个类,python会计算出一个方法解析顺序(MRO)列表,这个MRO列表就是一个简单的所有基类的线性顺序列表,python会在MRO列表上从左到右开始查找基类,直到找到第一个匹配这个属性的类为止。
补充: 类名.mro()可以查看该类对应的MRO表
多重继承:
Class 类名(要继承的类1,要继承的类2):
子类的代码块
注意:当子类继承类多个类的时候,当多个父类的成员方法名不相同时候,则子类都可以进行访问调用,如果多个父类的成员方法的方法名是相同的时候,则当子类调用时候,只按照继承顺序的先后进行调用,调用一次后,不会在调用。
Eg:
class Base1:
def fool(self):
print(“我是Bool1”)
class Base2:
def fool(self):
print(“我是Bool2”)
class C(Base1, Base2):
pass
c = C()
c.fool()
实行结果:我是Bool1
类的组合:把类的实例化放到新类里面,一般是把几个不是继承关系的类放到一起(没有纵向关系(继承关系),有横向关系)
补充:一个类的成员变量可以是另一个类的实例化对象(两个类之间没有继承关系)
Eg:
class Turtle:
def init(self, x):
self.num = x
class Fish:
def init(self, x):
self.num = x
class Pool:
def init(self, x, y):
self.turtle = Turtle(x)
self.fish = Fish(y)
def display(self):
print(self.turtle.num, self.fish.num, sep="\t")
pool = Pool(2,9)
pool.display()
实行结果:2 9
注解:Pool类中的成员变量分别是Turtle和Fish的实例化对象
程序调用顺序:
1.Pool实例化对象,调用Pool的构造函数,将两个参数传入,在构造函数中,对Turtle和Fish分别实例化对象,将传入Pool构造函数的两个参数传入到Turtle和Fish实例化的构造函数中,实例化turtle和fish作为Pool的实例化对象pool的成员变量.pool调用display()函数时,又分别访问了turtle和fish的成员变量num。
继承有两种用途:
一:继承基类的方法,并且做出自己的改变或者扩展(代码重用)
二:声明某个子类兼容于某基类,定义一个接口类Interface,接口类中定义了一些接口名(就是函数名)且并未实现接口的功能,子类继承接口类,并且实现接口中的功能

补充:
当类之间有显著不同,并且较小的类是较大的类所需要的组件时,用组合比较好
类,类对象,实例对象
1.对象属性,实例化对象属性
以下代码中,类:C 类对象:CC 实例化对象:a,b,d
class C:
count = 0
a = C()
b = C()
d = C()
print(a.count, b.count, d.count) # 1
d.count += 10
print(a.count, b.count, d.count) # 2 修改的是d的实例化对象属性,发生变化的是d的count属性,a和b是分别实例化的它们的值不会修改
C.count = 100
print(a.count, b.count, d.count) # 3 修改的是类C的静态属性值,a和c没对其实例化属性修改过,而d之前对实例化对象的属性赋值,覆盖了类的静态属性
实行结果:
0 0 0
0 0 10
100 100 10

2.实例化对象的属性和方法相同,则属性覆盖方法
class A:
def display(self):
print(“AAAAA”)
a = A()
a.display()
a.display = 1 #python中对象不需要声明,直接赋值就是定义。给实例化对象a的display属性直接赋值,该属性和方法名相同,则属性名直接将方法名覆盖掉
a.display()
实行结果:
AAAAA
Traceback (most recent call last):
File “E:/project/作业_20180821.py”, line 372, in
a.display()
TypeError: ‘int’ object is not callable

Python中约定俗成的规定:
1.不要试图在一个类里定义所有能想到的特性和方法,应该利用继承和组合机制进行拓展
2.用不同的词性命名,如属性名用名词,方法名用动词
绑定
定义:python严格要求方法需要有实例才能被调用,这种限制就是绑定
1.
class A:
def display():
print(“AAAAA”)
A.display() # 类对象A直接调用displa方法不会报错
a = A()
a.display() # 实例化对象a直接调用display方法会报错,因为调用display时把a当作参数传进去了,完整的调用方法a.display(a)
实行结果:
AAAAA
Traceback (most recent call last):
File “E:/project/作业_20180821.py”, line 379, in
a.display()
TypeError: display() takes 0 positional arguments but 1 was given
2.
class CC:
def setXY(self, x, y):
self.x = x
self.y = y
def printXY(self):
print(self.x, self.y)
dd = CC()
print(“dd:dict”, dd.dict) # 查看对象所有的属性,返回一个字典的类型。字典中只有实例对象的属性,不显示类属性和特殊属性(魔术方法)
print(“CC:dict”, CC.dict) # 键表示属性名,值就是属性的值
dd.setXY(4, 6)
print(“dd:dict”, dd.dict) # 这x,y只属于dd这个实例化对象
print(“CC:dict”, CC.dict) # 类属性中,没有4和6,这归功于绑定,实例化对象dd调用setxy(4,5)实际上将自身当作参数传入进去,完整的函数是dd.setxy(dd,4,6),在函数中赋值是dd.x = 4,dd.y = 6,所以4,6只属于dd
del CC

ee = CC() # 出错,类对象已经删除

dd.printXY()

实行结果:
dd:dict {}
CC:dict {‘module’: ‘main’, ‘setXY’: <function CC.setXY at 0x00000000029D7598>, ‘printXY’: <function CC.printXY at 0x00000000029D7620>, ‘dict’: <attribute ‘dict’ of ‘CC’ objects>, ‘weakref’: <attribute ‘weakref’ of ‘CC’ objects>, ‘doc’: None}
dd:dict {‘x’: 4, ‘y’: 6}
CC:dict {‘module’: ‘main’, ‘setXY’: <function CC.setXY at 0x00000000029D7598>, ‘printXY’: <function CC.printXY at 0x00000000029D7620>, ‘dict’: <attribute ‘dict’ of ‘CC’ objects>, ‘weakref’: <attribute ‘weakref’ of ‘CC’ objects>, ‘doc’: None}
4 6

注意:类中定义的属性和方法是静态变量,就算类对象被删除了,它们还是存放在内存中,只有在程序退出时候,它们才会被释放。(建议编程时使用实例属性,不要使用类属性)
与类,对象相关的BIF(内置函数)
1.issubclass(class1,class2)
如果class1是class2的子类就返回True
注意:1.检查是非严格行的检查(一个类也是本身的子类)
2.class2类对象组成的元组,只要class1是其中任何一个候选类的子类则返回True
3.其他情况会抛出一个TypeError异常
2.isinstance(class1,class2)
注意:1.如果第一个参数传的不是对象类型,则永远返回False
2.第二个参数不是类或者不是由类组成的元组,则抛出一个TypeError的异常
3.第一个参数是一个类的实例化对象,第二个是这个类对象时,返回True
3.hasattr(object,name)
查询对象是否有指定的属性
第一个是对象,第二个是属性名,用双引号串起来,否则报错
4.getattr(object,name[,default])
返回对象指定的属性值,如果该对象没有其属性,则返回制定的默认值,如果没有属性还有没有设定默认返回值,则抛出一个AttrbuteError异常
5.setattr(object,name,value)
如果对象没有属性值,则设定对象指定的属性值,
6.delattr(object,name)
删除对象是否有指定的属性,如果对象没有其属性值,则抛出一个AttrbuteError异常
注意:object可为实例化对象,也可为类对象
7.property(fget = None , fset=None , fdel = None, doc=None)
含义:通过属性来设置属性,第一个参数获得属性的方法,第二个参数设置属性的方法,第三个参数删除属性的方法。
优点:不需要修改接口a,只需要修改函数名和property的参数名,通过一个或多个魔术发方法实现
class DD:
def init(self, x = 10):
self.x = x
def getx(self):
return self.x
def setx(self, x):
self.x = x
def delx(self):
del self.x
a = property(getx, setx, delx)

dd = DD()
print(dd.getx())
print(dd.x)
print(dd.a)
dd.a = 19
print(dd.getx())
print(dd.x)
print(dd.a)
del dd.a
print(dd.getx()) #运行时会报错
print(dd.x)
print(dd.a)
实行结果:
10
10
10
19
19
19

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值