类和对象
1. 一个例子
# 对象 = 属性 + 方法
# Python 中的类名称约定首字母大写,而 Python 函数名首字母小写
class Turtle:
#属性
color = 'green'
weight = 10
legs = 4
shell = True
mouth = '大嘴'
# 方法
# 这里的 self 表示 this 指针
def climb(self):
print("我正在很努力地向前爬")
def run(self):
print("我正在飞快地向前跑")
def bite(self):
print("我咬死你咬死你")
def eat(self):
print("有得吃,真满足!")
def sleep(self):
print("困了,睡觉,晚安")
tt = Turtle()
tt.climb()
tt.bite()
tt.sleep()
我正在很努力地向前爬
我咬死你咬死你
困了,睡觉,晚安
2. 面向对象的特征
① 封装
# 我们只知道这些方法如何调用,并不知道方法内部怎么实现的
list1 = [2,1,7,5,3]
list1.sort()
list1.append(9)
print(list1)
[1, 2, 3, 5, 7, 9]
② 继承
class MyList(list): # 这里表示 Mylist 类继承于 list 类
# pass 为占位符,表明不做任何操作
pass
list2 = MyList()
# list 类中的方法都被继承了
list2.append(1)
list2.append(7)
list2.append(5)
list2.append(4)
list2.append(9)
list2.sort()
print(list2)
[1, 4, 5, 7, 9]
③ 多态
# 不同对象对同一方法响应不同的行动
class A:
def fun(self):
print("我是小A")
class B:
def fun(self):
print("我是小B")
a = A()
b = B()
a.fun()
b.fun()
我是小A
我是小B
3. self
# 当一个对象的方法被调用时,会将自身作为参数传入
# 类的方法定义时,必须把 self 写入第一个参数
class Ball:
def setName(self,name):
self.name = name
def kick(self):
print("我叫%s,该死的,谁踢我。。。" % self.name)
a = Ball()
a.setName('球A')
b = Ball()
b.setName('球B')
c = Ball()
c.setName('球C')
a.kick()
b.kick()
c.kick()
我叫球A,该死的,谁踢我。。。
我叫球B,该死的,谁踢我。。。
我叫球C,该死的,谁踢我。。。
4. _ _ init _ _ (self)(这里是两个双下划线)
class Ball:
# 这个即为构造函数
def __init__(self,name):
self.name = name
def kick(self):
print("我叫%s,该死的,谁踢我。。。" % self.name)
b = Ball('土豆')
b.kick()
我叫土豆,该死的,谁踢我。。。
5. 公有和私有
class Person:
name = '小甲鱼'
p = Person()
print(p.name)
小甲鱼
class Person:
# 变量前加上双下划线就会变成私有变量,无法直接调用
__name = '小甲鱼'
# 可以通过方法来调用
def getName(self):
return self.__name
p = Person()
print(p.name)
-------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-23-e128ce7b44b9> in <module>()
5 return self.__name
6 p = Person()
----> 7 print(p.name)
AttributeError: 'Person' object has no attribute 'name'
print(p.getName())
小甲鱼
# 其实 Python 的私有为伪私有,只是将变量的名字改了(名字改编)
# 可以通过 对象名._类名__变量名 来调用
print(p._Person__name)
小甲鱼
6. 继承
class Parent:
def hello(self):
print("正在调用父类的方法。。。")
class Child(Parent):
pass
p = Parent()
p.hello()
c = Child()
c.hello()
正在调用父类的方法。。。
正在调用父类的方法。。。
class Child1(Parent):
# 如果在子类中定义与父类同名的方法或属性,则会覆盖父类相应的方法或属性
def hello(self):
print("正在调用子类的方法。。。")
d = Child1()
d.hello()
p.hello()
正在调用子类的方法。。。
正在调用父类的方法。。。
7. 继承例子
import random as r
class Fish:
def __init__(self):
self.x = r.randint(0,10)
self.y = r.randint(0,10)
def move(self):
self.x -= 1
print("我现在的位置是:", self.x, self.y)
class Goldfish(Fish):
pass
class Carp(Fish):
pass
class Salmon(Fish):
pass
class Shark(Fish):
def __init__(self):
self.hungry = True
def eat(self):
if self.hungry:
print("吃货的梦想就是天天有得吃")
self.hungry = False
else:
print("太撑了,吃不下了!")
fish = Fish()
fish.move()
我现在的位置是: 3 6
fish.move()
我现在的位置是: 2 6
goldfish = Goldfish()
fish.move()
我现在的位置是: 1 6
shark = Shark()
shark.eat()
吃货的梦想就是天天有得吃
# 由于 Shark 子类重写了 __init__ 方法,属性 x 和 y,都不存在了,所以会报错
shark.move()
-------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-44-e54bb3f218a2> in <module>()
----> 1 shark.move()
<ipython-input-35-3f1e9b36930e> in move(self)
5 self.y = r.randint(0,10)
6 def move(self):
----> 7 self.x -= 1
8 print("我现在的位置是:", self.x, self.y)
9
AttributeError: 'Shark' object has no attribute 'x'
class Shark1(Fish):
def __init__(self):
# 这里调用未绑定的父类方法
# 这里的 self 是子类的对象,即将子类对象作为参数传入父类的构造方法
# 从而定义了属性 x 和 y
Fish.__init__(self)
self.hungry = True
def eat(self):
if self.hungry:
print("吃货的梦想就是天天有得吃")
self.hungry = False
else:
print("太撑了,吃不下了!")
shark1 = Shark1()
shark1.eat()
shark1.move()
吃货的梦想就是天天有得吃
我现在的位置是: 8 9
class Shark2(Fish):
def __init__(self):
# 也可以使用super
super().__init__()
self.hungry = True
def eat(self):
if self.hungry:
print("吃货的梦想就是天天有得吃")
self.hungry = False
else:
print("太撑了,吃不下了!")
shark2 = Shark2()
shark2.eat()
shark2.move()
吃货的梦想就是天天有得吃
我现在的位置是: 5 9
8. 多重继承
# 尽量避免使用多重继承
class Base1:
def foo1(self):
print("我是foo1,我为Base1代言。。。")
class Base2:
def foo2(self):
print("我是foo2,我为Base2代言。。。")
class C(Base1, Base2):
pass
c = C()
c.foo1()
c.foo2()
我是foo1,我为Base1代言。。。
我是foo2,我为Base2代言。。。
9. 组合
class Turtles:
def __init__(self, x):
self.num = x
class Fishs:
def __init__(self, x):
self.num = x
class Pool:
def __init__(self, x, y):
# 把类的实例化放到一个新类中,这样就可以避免使用多重继承
self.turtles = Turtles(x)
self.fishs = Fishs(y)
def print_num(self):
print("水池里总共有乌龟 %d 只,小鱼 %d 条!" % (self.turtles.num, self.fishs.num))
pool = Pool(1,10)
pool.print_num()
水池里总共有乌龟 1 只,小鱼 10 条!
10. Mix-in 编程机制
见 https://fishc.com.cn/forum.php?mod=viewthread&tid=48888&highlight=Mix
11. 类、类对象和实例对象
# 在定义的时候他是一个类,等他定义完就是一个类对象
class C:
count = 0
a = C()
b = C()
c = C()
print(a.count)
print(b.count)
print(c.count)
0
0
0
# 这里相当于生成了一个对象来覆盖了原来的count
# 类中定义的属性都是静态属性
# 类属性和类对象是相互绑定的,并不依赖于实例对象
# 当执行 c.count += 10 的时候,c实例对象里面多出了一个count属性
# 这个实例属性将类属性给覆盖了
c.count += 10
print(c.count)
print(a.count)
print(b.count)
10
0
0
C.count += 100
print(a.count)
print(b.count)
print(c.count)
100
100
10
12. 属性和方法同名
class D:
def x(self):
print("X-man!")
d = D()
d.x()
X-man!
# 这里是在实例对象里创建一个新的变量x,与方法同名,会覆盖方法
d.x = 1
print(d.x)
1
d.x()
-------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-84-a03010f95e9e> in <module>()
----> 1 d.x()
TypeError: 'int' object is not callable
- 不要试图在一个类里边定义出所有能想到的特性和方法,应该利用继承和组合机制来进行扩展。
- 用不同的词性命名,如属性名用名词,方法名用动词。
13. 绑定
Python要求方法需要有实例才能被调用,即为绑定
class BB:
# 这里没写参数 self
def printBB():
print("no zuo no die")
# 直接用类名可以调用
BB.printBB()
no zuo no die
# 由于没有 self 参数,所以实例化对象没办法调用该方法
bb = BB()
bb.printBB()
-------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-87-65bc6f83f641> in <module>()
1 bb = BB()
----> 2 bb.printBB()
TypeError: printBB() takes 0 positional arguments but 1 was given
class CC:
# 方法是静态的,绑定在类对象中
def setXY(self, x, y):
self.x = x
self.y = y
def printXY(self):
print(self.x, self.y)
dd = CC()
# 以字典方式输出 dd 对象所有的属性
print(dd.__dict__)
# 只有实例对象的属性,不显示类属性和特殊属性(魔法方法)
# 键用引号引起来,表示属性名
# 值表明属性对应的值
print(CC.__dict__)
{}
{'__module__': '__main__', 'setXY': <function CC.setXY at 0x00000159506896A8>, 'printXY': <function CC.printXY at 0x00000159506891E0>, '__dict__': <attribute '__dict__' of 'CC' objects>, '__weakref__': <attribute '__weakref__' of 'CC' objects>, '__doc__': None}
# 这里调用实际上调用的是dd.setXY(dd,4,5)
# x,y 变量储存在 dd 实例对象的空间中
dd.setXY(4,5)
# 这里的 x, y 仅属于dd
print(dd.__dict__)
print(CC.__dict__)
{'x': 4, 'y': 5}
{'__module__': '__main__', 'setXY': <function CC.setXY at 0x00000159506896A8>, 'printXY': <function CC.printXY at 0x00000159506891E0>, '__dict__': <attribute '__dict__' of 'CC' objects>, '__weakref__': <attribute '__weakref__' of 'CC' objects>, '__doc__': None}
del CC
ee = CC()
-------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-99-55ea04a3e7cb> in <module>()
1 del CC
----> 2 ee = CC()
NameError: name 'CC' is not defined
# 虽然类对象已经被删除,但是实例对象已经储存在内存中,仍然可以使用
# 只有在程序退出时才会被释放
# 所以大多数情况下应该使用实例属性,而不要去使用类属性
dd.printXY()
4 5
14.一些BIF
① issubclass(class,classinfo)
如果 clss 是 classinfo 的子类,就会返回TRUE
- 一个类会被认为是其自身的子类
- classinfo可以是类对象组成的元组,只要class是其中任何一个候选类的子类,则会返回True
class A:
pass
class B(A):
pass
class C:
pass
print(issubclass(B,A))
print(issubclass(B,B))
# 所有类都是object类的子类
print(issubclass(B,object))
print(issubclass(B,C))
True
True
True
False
② isinstance(object,classinfo)
如果 object 是 classinfo 的实例对象,就会返回TRUE
- 如果第一个参数不是对象,则永远返回False
- classinfo可以是类对象组成的元组,只要object是其中任何一个候选类的实例对象,则会返回True
- 如果第二个参数不是类或者由类对象组成的元组,会抛出一个TypeError
b1 = B()
print(isinstance(b1,B))
# B类继承于A类
print(isinstance(b1,A))
print(isinstance(b1,C))
print(isinstance(b1,(A,B,C)))
True
True
False
True
③ hasattr(object,name)
测试object对象里面是否有属性name
class D:
def __init__(self,x=0):
self.x = x
d1 = D()
# 这里的属性名参数,必须加上引号,否则会报错
print(hasattr(d1,'x'))
True
④ getattr(object,name[,default])
返回对象指定的属性值,如果属性不存在,如果你还设置了default,则会打印出default;如果没设置,则会抛出AttributeError的异常
print(getattr(d1,'x'))
0
print(getattr(d1,'y'))
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-12-bae8070f3f96> in <module>()
----> 1 print(getattr(d1,'y'))
AttributeError: 'D' object has no attribute 'y'
print(getattr(d1,'y','您所访问的属性不存在'))
您所访问的属性不存在
⑤ setattr(object,name,value)
设置对象中指定属性的值,如果没有,则会新建并赋值
setattr(d1,'y','Nigream')
print(getattr(d1,'y'))
Nigream
⑥ delattr(object,name)
删除对象中指定的属性,如果不存在则抛出AttributeError的异常
delattr(d1,'y')
delattr(d1,'y')
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-16-88d9b933b227> in <module>()
----> 1 delattr(d1,'y')
AttributeError: y
⑦ property(fget=None, fset=None, fdel=None, doc=None)
通过属性来设置属性
- fget为获取属性的方法,当执行e1.x语句时调用
- fset为设置属性的方法,当执行e1.x=18语句时调用
- doc为删除属性的方法,当执行del e1.x语句时调用
class E:
def __init__(self,size=10):
self.size = size
def getSize(self):
return self.size
def setSize(self,value):
self.size = value
def delSize(self):
del self.size
x = property(getSize,setSize,delSize)
e1 = E()
print(e1.getSize())
10
print(e1.x)
10
e1.x = 18
print(e1.x)
18
print(e1.getSize())
18
del e1.x
e1.size
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-53-2b22d88d2a9b> in <module>()
----> 1 e1.size
AttributeError: 'E' object has no attribute 'size'
Python学习笔记——类和对象的更多相关文章
-
《python基础教程(第二版)》学习笔记 类和对象(第7章)
<python基础教程(第二版)>学习笔记 类和对象(第7章) 定义类class Person: def setName(self,name): self.name=n ...
-
Python学习笔记之类与对象
这篇文章介绍有关 Python 类中一些常被大家忽略的知识点,帮助大家更全面的掌握 Python 中类的使用技巧 1.与类和对象相关的内置方法 issubclass(class, classinfo) ...
-
python学习笔记4(对象/引用;多范式; 上下文管理器)
### Python的强大很大一部分原因在于,它提供有很多已经写好的,可以现成用的对象 21. 动态类型:对象/引用 对象和引用: 对象是储存在内存中的实体,对象名只是指向这一对象的引用(refere ...
-
python学习笔记8--面向对象编程
一.面向对象编程 面向对象--Object Oriented Programming,简称oop,是一种程序设计思想.在说面向对象之前,先说一下什么是编程范式,编程范式你按照什么方式来去编程,去实现一 ...
-
Java学习笔记--类和对象
1.介绍面向对象的编程 面向对象是现在主流的编程样例,它替代了以前C语言使用时的“结构体”,Java是一门面向对象的语言,所以需要熟悉面向对象的概念.面向对象的程序由很多对象组成,每 ...
-
scala学习笔记——类和对象
基础语法关于Scala程序,这是非常要注意以下几点. 区分大小写 - Scala是大小写敏感的,这意味着标识Hello 和 hello在Scala中会有不同的含义. 类名 - 对于所有的类名的第一个字 ...
-
Python学习笔记总结(一)对象和流程语句总结
一.对象类型 1.数字 数字:不可变 2.字符串 字符串:不可原处修改[修改需要创建新的对象],有顺序,支持求长(len),合并(+),重复(*),索引S[0],分片(S[1:3]],成员测试(in) ...
-
python学习笔记8--面向对象--属性和方法详解
属性: 公有属性 (属于类,每个类一份) 普通属性 (属于对象,每个对象一份) 私有属性 (属于对象,跟普通属性相似,只是不能通过对象直接访问) 方法:(按作用) 构造方法 析构函数 方法: ...
-
webdriver(python)学习笔记六——操作测试对象
定位到具体对象后,就需要对其进行操作,比如点击.输入内容等. 一般来说,webdriver中比较常用的操作对象的方法有下面几个 click 点击对象 send_keys 在对象上模拟按键输入 clea ...
随机推荐
-
云计算之路-阿里云上:13:43-13:44之间RDS故障影响了全站的正常访问
抱歉!13:43-13:44之间,由于阿里云RDS(云数据库)出现2分钟突发故障,影响了全站的正常访问,给大家带来了麻烦,望大家谅解! 故障期间,应用程序日志中记录的错误信息如下: System.Da ...
-
hibernate学习——Set集合配置
Set集合的配置 数据表的创建:表关系一个员工拥有多个身份 create table EMPLOYEE ( id INT NOT NULL auto_increment, first_name VAR ...
-
【原】无脑操作:Windows 10 + MySQL 5.5 安装使用及免安装使用
本文介绍Windows 10环境下, MySQL 5.5的安装使用及免安装使用 资源下载: MySQL安装文件:http://download.csdn.net/detail/lf19820717/9 ...
-
Python之Django环境搭建(MAC+pycharm+Django++postgreSQL)
Python之Django环境搭建(MAC+pycharm+Django++postgreSQL) 转载请注明地址:http://www.cnblogs.com/funnyzpc/p/7828614. ...
-
confirm显示数组中的内容时,总是带一个逗号分隔的解决方法
问题的关键 就是在给confirm显示之前,将数组转换成字符串,并以每个数组的元素为一个字符串,加上一个换行回车符即可: 代码中的背景色 为关键的点 <script type="tex ...
-
cena评测系统:自定义校验器(自定义评测插件编写)
Cena评测系统,最受欢迎的信息学竞赛离线评测系统. 它是开放源程序的信息学竞赛评测系统,能满足大多数程序设计竞赛的测评需求. 特色功能: 通过局域网自动收取选手程序. 高效率的数据文件配置工具. 自 ...
-
Jenkins日常运维笔记-重启数据覆盖问题、迁移、基于java代码发版(maven构建)
之前在公司机房部署了一套jenkins环境,现需要迁移至IDC机房服务器上,迁移过程中记录了一些细节:1)jenkins默认的主目录放在当前用户家目录路径下的.jenkins目录中.如jenkins使 ...
-
linux OS与SQL修改时区,系统时间
linux修改系统时间和linux查看时区.修改时区的方法 一.查看和修改Linux的时区 1. 查看当前时区命令 : "date -R" 2. 修改设置Linux服务器时区方法 ...
-
第三节 循环链表的Go语言实现
一.什么是循环链表 循环链表的节点形成一个圈.把单链表的尾巴指向开头形成单循环链表.把双向链表的尾巴与开头链接起来就形成双向循环链表.使用循环链表可以不断的绕圈寻找所需要的数据,而不需要像单链表那样每 ...
-
超酷算法-BK树
前几天无意间遇到一个博客,觉得写得挺好的,自己之前的时候有个不好的习惯,那就是遇到了好资源第一反应就是收藏起来然后却很少再看!!这是坏习惯,要改!于是今天就开始通读了,读的第二篇是BK树.觉得有点意思 ...