Python之路,第十九篇:Python入门与基础19
python3 面向对象3
数值转换函数重载:
str(obj) __str__
complex(x) __complex__
int(obj) __int__
float(obj) __float__
bool __bool__
class MyNumber:
def __init__(self,n):
self.data = n def __float__(self):
print("__float__被调用。")
try:
x = float(self.data)
except:
x = 0.0
return x n = MyNumber('')
print(float(n)) #__float__被调用。 #100.0 print(float("100.0")) #100.0
print(float(True)) #1.0 n = MyNumber(1+2j)
print(float(n)) #__float__被调用。 #0.0
bool 测试运算符重载:
方法格式:def __bool__(self):
.......
作用:1, 用于if 语句的真值表达式中:
2, 用于while 语句的真值表达式中;
3,用于bool(obj) 函数取值;
说明:当没有__bool__ (self)方法时, 真值测试将以__len__(self)的方法的返回值来进行测试布尔值;
class MyList:
def __init__(self, count=0, value =0):
self.data = []
for x in range(count):
self.data.append(value) def __repr__(self):
return "MyList("+ repr(self.data) +")" def __bool__(self):
print("__bool__被调用")
for x in self.data:
if x:
return True #如果遇到一个真值,直接返回true,不在执行下面的语句
return False #myl = MyList(10)
#print(myl) #MyList([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) #__bool__被调用 #MyList为假值
myl = MyList(10,1)
print(myl)
if myl:
print("MyList 为真值")
else:
print("MyList为假值")
#MyList([1, 1, 1, 1, 1, 1, 1, 1, 1, 1])
#__bool__被调用
#MyList 为真值
#
class MyList:
def __init__(self, count=0, value =0):
self.data = []
for x in range(count):
self.data.append(value) def __repr__(self):
return "MyList("+ repr(self.data) +")" def __len__(self):
return len(self.data)
#def __bool__(self): #如果有__len__存在,__bool__优先执行;
# print("__bool__被调用")
# for x in self.data:
# if x:
# return True #如果遇到一个真值,直接返回true,不在执行下面的语句
# return False #myl = MyList(10)
#print(myl)#MyList([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
# MyList 为真值
myl = MyList(10,1)
print(myl)
if myl:
print("MyList 为真值")
else:
print("MyList为假值")
#MyList([1, 1, 1, 1, 1, 1, 1, 1, 1, 1])
#MyList 为真值
in / not in 运算符重载:
重载方法:
def __contains__(self, e):
pass
class even:
"偶数类,用于显示偶数的有序列表"
def __init__(self, begin, end):
self.begin = begin
self.end = end #不包含end def __contains__(self, e):
print("__contains__被调用")
if e < self.begin:
return False if e >= self.end:
return False if e % 2 == 0:
return True return False e1 = even(1, 10)
if 4 in e1:
print("4 在e1中") if 3 in e1:
print("3 在e1中")
else:
print("3 不在e1中") if 30 not in even(10, 20):
print("30不在even(10, 20)中") #__contains__被调用
#4 在e1中
#__contains__被调用
#3 不在e1中
#__contains__被调用
#30不在even(10, 20)中
练习1:定义一个素数的类;
class Primes:
def __init__(self, end):
"""end 用于表示素数的终止点,素数的起点是2包含2"""
self.end = end def __contains__(self, element):
def isprime(x):
for i in range(2, x):
if x % 2 == 0:
return False
return True
if element < 2:
return False
if element >= self.end:
return False
return isprime(element) p1 = Primes(100)
if 50 in p1:
print("50是素数")
else:
print("50不是素数"
def isprime(x):
for i in range(2, x):
if x % 2 == 0:
return False
return True
class Primes:
def __init__(self, end):
"""end 用于表示素数的终止点,素数的起点是2包含2"""
self.end = end def __contains__(self, element):
#def isprime(x):
# for i in range(2, x):
# if x % 2 == 0:
# return False
# return True if element < 2:
return False
if element >= self.end:
return False
return isprime(element) p1 = Primes(100)
if 50 in p1:
print("50是素数")
else:
print("50不是素数")
class Primes:
def __init__(self, end):
"""end 用于表示素数的终止点,素数的起点是2包含2"""
self.end = end @staticmethod
def isprime(x):
for i in range(2, x):
if x % 2 == 0:
return False
return True def __contains__(self, element):
#def isprime(x):
# for i in range(2, x):
# if x % 2 == 0:
# return False
# return True if element < 2:
return False
if element >= self.end:
return False
return self.isprime(element) p1 = Primes(100)
if 50 in p1:
print("50是素数")
else:
print("50不是素数")
索引和切片运算符的重载:
__getitem__(self, i) # 索引/切片获取值
__getitem__(self, i , value) #设置索引或切片的值;
__delitem__(self, i) #进行删除索引操作
作用:让自定义的对象能进行索引和切片操作;
class MyList:
def __init__(self, count=0, value=0):
self.data = []
for x in range(count):
self.data.append(value) def __repr__(self):
return "MyList("+ repr(self.data) +")" def setValueAt(self,index, value):
self.data[index] = value
#return self myl = MyList(5, 1)
print(myl) #MyList([1, 1, 1, 1, 1])
#myl[1] = 2
#print(myl.setValueAt(1, 2)) #return self
myl.setValueAt(1, 2)
print(myl)
===========================
class MyList:
def __init__(self, count=0, value=0):
self.data = []
for x in range(count):
self.data.append(value) def __repr__(self):
return "MyList("+ repr(self.data) +")" #def setValueAt(self,index, value):
# self.data[index] = value
# #return self
def __setitem__(self, index, value):
self.data[index] = value myl = MyList(5, 1)
print(myl) #MyList([1, 1, 1, 1, 1]) myl[1] = 2
print(myl) #MyList([1, 2, 1, 1, 1])
class MyList:
def __init__(self, count=0, value=0):
self.data = []
for x in range(count):
self.data.append(value) def __repr__(self):
return "MyList("+ repr(self.data) +")" def __setitem__(self, index, value):
self.data[index] = value def __getitem__(self, index):
print("__getitem__被调用")
return self.data[index] myl = MyList(5, 1)
print(myl) #MyList([1, 1, 1, 1, 1]) myl[1] = 2
print(myl) #MyList([1, 2, 1, 1, 1])
#
print(myl[0]) #__getitem__被调用, #1
class MyList:
def __init__(self, count=0, value=0):
self.data = []
for x in range(count):
self.data.append(value) def __repr__(self):
return "MyList("+ repr(self.data) +")" def __setitem__(self, index, value):
self.data[index] = value def __getitem__(self, index):
print("__getitem__被调用")
return self.data[index] def __delitem__(self, index):
if index >= len(self.data):
raise IndexError("%d在不予许的范围内" % index) if index < -len(self.data):
raise IndexError("%d在不予许的范围内" % index)
del self.data[index]
#以下示意不予许用del,进行索引操作
#print("__delitem__被调用,index:", index)
#print("del 啥也不做!")
#raise TypeError myl = MyList(5, 1)
print(myl) #MyList([1, 1, 1, 1, 1]) myl[1] = 2
print(myl) #MyList([1, 2, 1, 1, 1])
#
print(myl[0]) #__getitem__被调用, #1
#
print(myl)
del myl[3]
print(myl)
#MyList([1, 2, 1, 1, 1])
#MyList([1, 2, 1, 1])
步长
class MyList:
def __init__(self, count=0, value=0):
self.data = []
for x in range(count):
self.data.append(value) def __repr__(self):
return "MyList("+ repr(self.data) +")" def __setitem__(self, index, value):
self.data[index] = value def __getitem__(self, index):
print("__getitem__被调用,index:",index)
if isinstance(index, int):
return self.data[index]
elif isinstance(index, slice):
print("开始值是:", index.start)
print("结束值是:", index.stop)
print("步长是:", index.step) def __delitem__(self, index):
if index >= len(self.data):
raise IndexError("%d在不予许的范围内" % index) if index < -len(self.data):
raise IndexError("%d在不予许的范围内" % index)
del self.data[index]
#以下示意不予许用del,进行索引操作
#print("__delitem__被调用,index:", index)
#print("del 啥也不做!")
#raise TypeError myl = MyList(5, 1)
print(myl) #MyList([1, 1, 1, 1, 1])
myl[1] = 2
myl[2] = 3
myl[3] = 4
myl[4] = 5
print(myl) #MyList([1, 2, 3, 4, 5])
print(myl[1])
print(myl[1:5:2]) #__getitem__被调用,index: slice(1, 5, 2)#[2, 4] L = [1,2,3,4,5,6,7,8,9]
print(L[1::2]) #[2, 4, 6, 8]
s = slice(1,10,2)
print(L[s]) ##[2, 4, 6, 8]
print(s.start) #
print(s.stop) #
print(s.step) #
print()
print(myl[slice(1,5,2)])
print(myl[:])
函数调用(模拟)重载:
__call__ 方法:
作用:让一个对象能像函数一样被调用;
方法格式: def __call__(self, 参数列表):
执行代码
注: 此重载方法的参数可以是1个或多个()
例: class A:
pas
a = A() #创建对象
a() #??/a能被调用吗?
class MySum:
def __init__(self):
self.data = 0 def __call__(self, *args, **kwargs):
#def __call__(self):
#def __call__(self, a, b):
"函数调用重载"
print("__call__被调用")
print("args",args, "kwargs",kwargs)
s = sum(args)
self.data += s
return s ms = MySum()
r = ms(100, 200)
print("r:",r)
r = ms(300, 400)
print("r:",r)
print("以前所有数之和:",ms.data)
#__call__被调用
#args (100, 200) kwargs {}
#r: 300
#__call__被调用
#args (300, 400) kwargs {}
#r: 700
#以前所有数之和: 1000#
迭代器(高级)
迭代器协议: 是指对象(实例)能够使用next函数获取下项数据,在没有下一项数据时触发一个StopIteration异常来终止迭代的约定;
next(it) 对应 __next__(self) 方法
iter(obj) 对应 __iter__(self)方法通常返回一个可迭代对象;
xxx
for 语句和推导式,先调用iter(obj)拿出迭代器,再迭代;
迭代器:
range() 生成器函数:
(x for x in range(10) ) 生成器表达式
迭代器协议:
1, 要有 __next__方法;
2, 无法取值产生StopIteration异常;
获取迭代器的方法;
__iter__方法,对象用于方法迭代器;
class Odd:
def __init__(self, begin, end):
self.begin = begin
self.end = end
self.cur = begin #数据的当前位置 def __next__(self):
print("__next__被调用")
if self.cur >= self.end:
raise StopIteration
if self.cur % 2 == 0:
self.cur += 1
r = self.cur
self.cur += 2
return r def __iter__(self):
print("__iter__被调用,返回字节作为迭代器")
self.cur = self.begin
return self #o = Odd(1, 10)
o = Odd(2, 10) # 奇数对象
for x in iter(o):
print(x) print([x for x in o])
#print(next(o))#1
#print(next(o))#3
#print(next(o))#5
#print(next(o))#7
#print(next(o))#9
#print(next(o))
#__iter__被调用,返回字节作为迭代器
#__iter__被调用,返回字节作为迭代器
#__next__被调用
#
#__next__被调用
#
#__next__被调用
#
#__next__被调用
#
#__next__被调用
#__iter__被调用,返回字节作为迭代器
#__next__被调用
#__next__被调用
#__next__被调用
#__next__被调用
#__next__被调用
#[3, 5, 7, 9]
#
L = [1,2,3]
it = iter(L)
id(it) == id(L)
False
it
<list_iterator object at 0x0000000003D10940>
L
[1, 2, 3]
异常(高级)
with 语句
语法: with 表达式 [ as 变量名 ]:
语句块
或:
with 表达式1 [ as 变量名1 ] [ ,表达式2 [ as 变量名2 ]....]:
语句块
说明:as 子句中的变量绑定生成的对象;
#f = open("file.txt",'r')
#while True:
# l = f.readline()
# print(l, end='')
# if len(l) == 0:
# break
#
#####
with open('file.txt','r') as f:
while True:
#3/0 #触发异常,但文件肯定会关闭
l = f.readline()
print(l, end='')
if len(l) == 0:
break
作用:使用于对资源进行访问的场合,确保使用过程中不管是否发生异常,都会执行必须的“清理” 操作,并释放资源;
环境管理器:
1,类内有__enter__ 和__exit__ 方法的类被称为环境管理器;
2,能够用with 语句进行管理的对象必须是环境管理器;
3,__enter__将进入with语句时被调用并返回由as变量管理对象;
4, __exit__ 将在离开with 时被调用, 且可以用参数来判断在离开with语句时是否有异常发生,并且做出相应的处理;
class Cooker:
def open_c(self):
print("正在打开火") def close_c(self):
print("正在关闭火") def doworks(self):
print("正在做饭") def __enter__(self):
self.open_c()
return self #此对象将被as绑定 def __exit__(self, exc_type, exc_val, exc_tb):
self.close_c()
if exc_type is None:
print("with语句正常退出")
else:
print("with语句异常退出", exc_val) with Cooker() as c:
c.doworks()
3/0
c.doworks() #正在打开火
#正在做饭
#正在关闭火
#Traceback (most recent call last):
# File "C:, line 23, in <module>
# 3/0
#ZeroDivisionError: division by zero# #正常处理
#c = Cooker()
#c.open_c()
#c.doworks()
#3/0
#c.doworks()
#c.close_c()
什么是继承(inheritance)/派生(derived)
什么是继承/派生
继承的目的是延续旧的功能;
派生的目的是在类旧类的基础上添加新的功能;
作用: 用继承派生机制,可以将一些共有功能加在基类中,实现代码共享,在不改变超类的代码的基础上改变原有功能;
名词: 基类(base class)/ 超类(supper class) /父类 (father class) /派生类(derived class) / 子类 (child class)
单继承语法:
class 类名(超类名):
。。。。
继承说明:任何类都直接或间接的继承自object类; object类是一切类的超类;
__base__属性:
作用:用来记录此类的基类(类实例);
覆盖override (也叫重写 overrite)
什么是覆盖:
覆盖是指由继承关系的类中,子类中实现了与基类(超类)同名的方法,在子类实例调用该方法时,实际调用的是子类中的覆盖版本,这种现象叫做覆盖;
子类对象显示调用基类方法的方式:
基类名。方法名。(实例,参数)
class Human:
def say(self):
print("say: hello,world!") def run(self, speed):
print("Human run km/h speed:", speed) class Student(Human):
def study(self, s):
print("Student study:", s) def run(self, speed):
print("Student run km/h speed:", speed) def walk(self, speed): #走的方法
#self.run(speed) #调用自身self #Student run km/h speed: 3
#self.__class__.run(self, speed) #调用自身 #self #Student run km/h speed: 3
self.__class__.__base__.run(self, speed) #借助于self自身调用父类的run方法
# #Human run km/h speed: 3 t1 = Human()
s1 = Student() t1.run(5)
s1.run(4)#Student run km/h speed: 4 #此时调用的是子类的覆盖版本的方法 #子类调用基类的版本(原版本)方法
Human.run(s1, 8) # Human run km/h speed: 8 s1.walk(3) #Student run km/h speed: 3
class Human:
def say(self):
print("say: hello,world!") def run(self, speed):
print("Human run km/h speed:", speed) class Teacher(Human):
def teach(self, te):
print("Teacher teach:", te) #def run(self, speed):
# print("Teacher run km/h speed:", speed) class Student(Teacher):
def study(self, s):
print("Student study:", s) #def run(self, speed):
# print("Student run km/h speed:", speed) def walk(self, speed): #走的方法
#self.run(speed) #调用自身self #Student run km/h speed: 3
#self.__class__.run(self, speed) #调用自身 #self #Student run km/h speed: 3
self.__class__.__base__.run(self, speed) #借助于self自身调用父类的run方法
# #Human run km/h speed: 3 t1 = Human()
t2 = Teacher()
s1 = Student() t1.run(5)
#s1.run(4)#Student run km/h speed: 4 #此时调用的是子类的覆盖版本的方法
t2.run(3.5)
s1.run(4) #子类调用基类的版本(原版本)方法
#Human.run(s1, 8) # Human run km/h speed: 8
#
#s1.walk(3) #Student run km/h speed: 3
Python之路,第十九篇:Python入门与基础19的更多相关文章
- Python之路(第二十九篇) 面向对象进阶:内置方法补充、异常处理
一.__new__方法 __init__()是初始化方法,__new__()方法是构造方法,创建一个新的对象 实例化对象的时候,调用__init__()初始化之前,先调用了__new__()方法 __ ...
- Python之路(第十九篇)hashlib模块
一.hashlib模块 HASH Hash,一般翻译做“散列”,也有直接音译为”哈希”的,就是把任意长度的输入(又叫做预映射,pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值 ...
- Python之路(第二十四篇) 面向对象初级:多态、封装
一.多态 多态 多态:一类事物有多种形态,同一种事物的多种形态,动物分为鸡类,猪类.狗类 例子 import abc class H2o(metaclass=abc.ABCMeta): def _ ...
- Python之路(第十五篇)sys模块、json模块、pickle模块、shelve模块
一.sys模块 1.sys.argv 命令行参数List,第一个元素是程序本身路径 2.sys.exit(n) 退出程序,正常退出时exit(0) 3.sys.version . sys.maxint ...
- Python之路(第十二篇)程序解耦、模块介绍\导入\安装、包
一.程序解耦 解耦总的一句话来说,减少依赖,抽象业务和逻辑,让各个功能实现独立. 直观理解“解耦”,就是我可以替换某个模块,对原来系统的功能不造成影响.是两个东西原来互相影响,现在让他们独立发展:核心 ...
- 【Python之路】第六篇--Python基础之模块
模块,用一砣代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,可能需要多个函数才 ...
- 【Python之路】第十九篇--Python操作MySQL
本篇对于Python操作MySQL主要使用两种方式: 原生模块 pymsql ORM框架 SQLAchemy pymsql pymsql是Python中操作MySQL的模块,其使用方法和MySQLdb ...
- Python开发【第十九篇】:Python操作MySQL
本篇对于Python操作MySQL主要使用两种方式: 原生模块 pymsql ORM框架 SQLAchemy pymsql pymsql是Python中操作MySQL的模块,其使用方法和MySQLdb ...
- Python之路(第二十八篇) 面向对象进阶:类的装饰器、元类
一.类的装饰器 类作为一个对象,也可以被装饰. 例子 def wrap(obj): print("装饰器-----") obj.x = 1 obj.y = 3 obj.z = 5 ...
- Python之路(第二十六篇) 面向对象进阶:内置方法
一.__getattribute__ object.__getattribute__(self, name) 无条件被调用,通过实例访问属性.如果class中定义了__getattr__(),则__g ...
随机推荐
- 记录一下ES6扩展运算符(三点运算符)...的用法
...运算符用于操作数组,有两种层面 1. 第一个叫做 展开运算符(spread operator),作用是和字面意思一样,就是把东西展开.可以用在array和object上都行. 比如: let a ...
- Talend 数据转换
2个系统都有客户信息,产品信息. 要从一个系统a导出数据给另一个系统b用. 有2个方法. 1.在a系统的客户表,产品表加一个字段,记录b系统对应的ID,导出时直接用sql转换了. 2. 用ETL工具转 ...
- vertical-align属性测试实验面板 文字 图片对齐
转自:http://www.zhangxinxu.com/study/201005/verticle-align-test-demo.html
- BeanUtils.copyProperties(A,B)使用注意事项
***最近项目中用到BeanUtils.copyProperties(),然后踩了一些坑,也在网上查看了很多同行的测试和总结,现在将自己的测试.整理的注意事项分享如下,希望大家一起学习进步. ***注 ...
- linux下文件内容查找 转
find | xargs grep test find命令和xargs命令 网友:wuye_chinaunix 发布于: : (共有条评论) 查看评论 | 我要评论 青云 分配文件 - -| 回首页 ...
- UVa 3602 - DNA Consensus String 水题 难度: 0
题目 https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_pr ...
- day28 黏包及黏包解决方案
今日主要内容: 一 .缓冲区 二.两种黏包现象 三.黏包现象的两种解决方案 四.打印进度条(补充的,了解即可) 1. 缓冲区 缓冲区的作用 : 将程序和网络解耦(这样做的好处是程序不会以为网速的快慢而 ...
- python 爬虫之 selenium API
一.浏览器操作 1.浏览器最大化 driver.maximize_window() #将浏览器最大化显示 2.设置浏览器宽.高 driver.set_window_size(480, 800)#设置浏 ...
- vue组件的使用和事件传递
子组件与父组件的事件传递具体实现如下: 子组件: <template> <section class="xftz-data-list"> <div c ...
- Linux学习 :多线程编程
1.Linux进程与线程() 进程:通过fork创建子进程与创建线程之间是有区别的:fork创建出该进程的一份拷贝,创建时额外申请了新的内存空间以及存储代码段.数据段.BSS段.堆.栈空间, ...