铁乐学python_day24_面向对象进阶1_内置方法

题外话1: 学习方法【wwwh】

what where why how

是什么,用在哪里,为什么,怎么用

学习到一个新知识点的时候,多问问上面的四个问题,并了解和实践透彻。

什么是反射?

先不说枯燥的概念,你可以自己总结出来,对于python中的反射,什么时候会用到?

需要使用字符串数据类型的变量名来使用变量的时候用到反射。

(通过字符串的形式操作对象相关的属性和方法。)

关键词:字符串

使用到字符串的场景多在:

1)文件中存储的是字符串,

2)网络上能传递的也最接近字符串,

3)用户输入的(用的不多,因为毕竟有安全隐患)

今天来学习内置方法的用处

(重写内置方法应用于个别需求)

__len__  len(obj)
obj对应的类中含有__len__方法,len(obj)才能正常执行。 __hash__ hash(obj) 是object类自带的
只有实现了__hash__方法,has(obj)才能正常执行。 题外话2: 列表和字典
需要循环遍历去寻找的用列表比字典好一点,例如遍历文件中保存的用户名和密码。
而需要快速由一个key找到一个值的,用字典好,比如用户登录状态。 __str__内置方法 和__repr__内置方法
print() # 向文件中写 print替你将数据类型转换成字符串打印出来。
print(obj) 的结果是obj.__str__()的结果。
str(obj) 的结果也是obj.__str__()的结果 (str是一个类名)。
'%s' % obj 的结果是也是obj.__str__()的结果。 repr(obj) 的结果和obj.__repr__()是一样的。
'%r' % obj 的结果和obj.__repr__()是一样的。 所有的输出本质上都是往文本上写。
print(lis) ---> lis.__str__() object类中的__str__就是默认返回一个数据的内存地址。
自己新建的类重写一下自己类中的__str__内置方法就可以人性化的输出。
重写内置方法为的是调用内置函数时输出的是自己想要的结果。 reps(1) 和 reps('1') 打印的结果不一样,
是因为class int 和class str 中的 __repr__方法不一样。
默认设计是让你区分不同。 当需要使用__str__的场景时,找不到__str__就找__repr__,
当需要使用__repr__的场景时,找不到__repr__的时候就找父类的repr。
双下repr是双下str的备胎。 len() obj.__len__() 返回值是一致的
不如这样说:len() 的结果是依赖 obj.__len__()
同理 hash()的结果是依赖 obj.__has__() str() 的结果是依赖 obj.__str__()
print(obj) 的结果是依赖 obj.__str__()
%s 的结果是依赖 obj.__str__() repr 的结果是依赖 obj.__repr__()
%r 的结果是依赖 obj.__repr__()
repr是str的备胎。 题外话3: 语法糖很甜
凡是不以函数调用方式出现的给予你便利的语法方式,都可以称为语法糖。
表面上语法只是很简单的方式,实际上后台都会落实到具体的方法上。 __format__方法
当你自己去实现双下format的时候,需要带有format_spec参数。
format_spec参数 :格式化的标准(规则),format内置函数规定的。
format_spec 在外部定义一个标准,为了让用户更灵活定制。 def format(*args, **kwargs): # real signature unknown
"""
Return value.__format__(format_spec) format_spec defaults to the empty string
"""
pass 例:
format_dict={
'nat':'{obj.name}-{obj.addr}-{obj.type}',#学校名-学校地址-学校类型 (默认输出格式)
'tna':'{obj.type}:{obj.name}:{obj.addr}',#学校类型:学校名:学校地址
'tan':'{obj.type}/{obj.addr}/{obj.name}',#学校类型/学校地址/学校名
}
class School:
def __init__(self,name,addr,type):
self.name=name
self.addr=addr
self.type=type def __repr__(self):
return 'School(%s,%s)' %(self.name,self.addr)
def __str__(self):
return '(%s,%s)' %(self.name,self.addr) def __format__(self, format_spec):
# if format_spec
if not format_spec or format_spec not in format_dict:
format_spec='nat'
fmt=format_dict[format_spec]
return fmt.format(obj=self) s1=School('oldboy1','北京','私立')
print('from repr: ',repr(s1))
print('from str: ',str(s1))
print(s1) '''
str函数或者print函数--->obj.__str__()
repr或者交互式解释器--->obj.__repr__()
如果__str__没有被定义,那么就会使用__repr__来代替输出
注意:这俩方法的返回值必须是字符串,否则抛出异常
'''
print(format(s1,'nat'))
print(format(s1,'tna'))
print(format(s1,'tan'))
print(format(s1,'asfdasdffd')) 题外话4:为什么要归一化设计呢?
1)更接近面向函数编程
2)简单且节省代码 __call__内置方法:
class Teacher():
def __call__(self):
print(123)
t = Teacher()
t()
对像名加(),相当于调用类内置的__call__ callable 检测对象能否被调用,返回布尔值。
一个对象是否可调用,取决于这个对象对应的类是否实现了__call__。
如果对象拥有内置双下call方法,就可以被调用了。 对象后面加括号,触发执行。
注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;
而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()() __eq__内置方法:
判断 == 这件事是由__eq__的返回值来决定的。 class A:
def __init__(self):
self.a = 1
self.b = 2 def __eq__(self,obj):
if self.a == obj.a and self.b == obj.b:
return True
a = A()
b = A()
print(a == b) __del__ 析构方法
所有面向对象语言都有的;
在删除一个对象的时候做一些收尾工作,比如说关闭一些打开的文件,断开一些网络链接等。 析构方法,当对象在内存中被释放时,自动触发执行。
注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,
因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。 class A:
def __init__(self):
self.f = open('File','w')
del __del__(self):
self.f.close
print('执行我啦') a = A()
del a
print('666') 运行完一个程序之后,python解释器会执行回收内存,自动运行双下del。 __new__ 构造方法
实例化的时候,init初始化之前,有一个创造对象的过程,
创造对象过程就是用内置的双下new方法,
先把小孩生下来才能给他穿衣服,先有对象再有初始化。 设计模式---单例模式(考到了双下new方法)
单例模式就是一个类只能有一个实例。
可以被多次实例化,但最终只会有一个实例存在。 # 使用双下new实现单例模式如下:
class Teacher():
__instance = None
def __init__(self, name, age):
self.name = name
self.age = age
def __new__(cls, *args, **kwargs):
if cls.__instance is None:
obj = object.__new__(cls)
cls.__instance = obj
return cls.__instance a = B('alex', 80)
b = B('egon', 20)
print(a)
print(b)
print(a.name)
print(b.name) item 系列 对象使用中括号的形式去操作(属性)
__getitem__\__setitem__\__delitem__
[]中括号的形式,字典的通过key找值的方式,通过双下getitem实现
__getitem__ 查询 对象名[属性名] 等同对象名.属性名
__setitem__ 设置 对象名[属性名]= 值 赋值和修改,新增
__delitem__ 删除 del 对象名[属性名] 等同del 对象名.属性
也相当于执行了__delattr__ 例:扑克牌游戏
class FranchDeck:
ranks = [str(n) for n in range(2, 11)] + list('JQKA')
# 直接拼接两个列表生成13张扑克牌,并且里面的元素同时转为字符串
suits = ['红心', '方块', '梅花', '黑桃'] def __init__(self):
self.cards = [(rank, suit) for rank in FranchDeck.ranks
for suit in FranchDeck.suits]
# 元组中的点数和花色分别推导循环得出
# [('2', '红心'), ('2', '方块'), ('2', '梅花'), ('2', '黑桃'), ('3', '红心')……] def __len__(self):
return len(self.cards)
# 统计扑克牌一共52张 def __getitem__(self, item):
return self.cards[item]
# 等同于列表切片,取出当中的元素 def __setitem__(self, key, value):
self.cards[key] = value deck = FranchDeck() # 实例化 # 对列表对象切片取值,下面两行是相同的
print(deck[0])
print(deck.__getitem__(0)) print(deck.ranks)
print(deck.cards) # 对列表统计元素,下面两行也是相同结果
print(len(deck))
print(deck.__len__()) # 随机选择扑克牌
from random import choice
print(choice(deck))
print(choice(deck)) # 设置对应索引位置为什么值
deck.__setitem__(0, ('3', '黑桃'))
deck[1] = ('3', '梅花')
print(deck[0]) # 取到的值不是红心2了,变成了黑桃3
print(deck[1]) # 取到的值不是方块2了,变成了梅花3 # shuffle = 洗牌,但每一次都要重新洗牌,不洗的话取出的是同一组
from random import shuffle
shuffle(deck)
print(deck[:5])
shuffle(deck)
print(deck[:13])
shuffle(deck) # 洗牌,然后切片发牌,将52张按序切完就可以玩扑克啦
print(deck[:13])
print(deck[13:26])
print(deck[26:39])
print(deck[39:52]) # [('7', '黑桃'), ('A', '方块'), ('Q', '梅花'), ('3', '梅花'), ('10', '方块'), ('K', '红心'), ('8', '黑桃'), ('J', '方块'), ('2', '黑桃'), ('5', '方块'), ('Q', '方块'), ('5', '红心'), ('9', '红心')]
# [('J', '梅花'), ('Q', '红心'), ('3', '红心'), ('4', '梅花'), ('10', '黑桃'), ('10', '梅花'), ('K', '黑桃'), ('7', '红心'), ('2', '梅花'), ('A', '梅花'), ('J', '黑桃'), ('2', '方块'), ('3', '黑桃')]
# [('7', '梅花'), ('K', '方块'), ('6', '红心'), ('J', '红心'), ('A', '红心'), ('4', '方块'), ('8', '方块'), ('4', '黑桃'), ('5', '梅花'), ('9', '黑桃'), ('3', '方块'), ('Q', '黑桃'), ('8', '红心')]
# [('4', '红心'), ('9', '梅花'), ('9', '方块'), ('6', '方块'), ('A', '黑桃'), ('6', '梅花'), ('10', '红心'), ('6', '黑桃'), ('K', '梅花'), ('5', '黑桃'), ('7', '方块'), ('2', '红心'), ('8', '梅花')] 面试题:
100个同一个类的对象,
Person 对象有同名,同性别,但不同年龄,进行去重。
class Person:
def __init__(self,name,age,sex):
self.name = name
self.age = age
self.sex = sex def __hash__(self):
return hash(self.name+self.sex) def __eq__(self, other):
if self.name == other.name and self.sex == other.sex:return True p_lst = []
for i in range(84):
p_lst.append(Person('egon',i,'male')) print(p_lst)
print(set(p_lst))

end

2018-4-19

铁乐学python_day24_面向对象进阶1_内置方法的更多相关文章

  1. 铁乐学python_day23_面向对象进阶1_反射

    铁乐学python_day23_面向对象进阶1_反射 以下内容大部分摘自博客http://www.cnblogs.com/Eva-J/ isinstance()和issubclass() 两者的返回值 ...

  2. Python之路(第二十九篇) 面向对象进阶:内置方法补充、异常处理

    一.__new__方法 __init__()是初始化方法,__new__()方法是构造方法,创建一个新的对象 实例化对象的时候,调用__init__()初始化之前,先调用了__new__()方法 __ ...

  3. Python之路(第二十七篇) 面向对象进阶:内置方法、描述符

    一.__call__ 对象后面加括号,触发执行类下面的__call__方法. 创建对象时,对象 = 类名() :而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()( ...

  4. Python之路(第二十六篇) 面向对象进阶:内置方法

    一.__getattribute__ object.__getattribute__(self, name) 无条件被调用,通过实例访问属性.如果class中定义了__getattr__(),则__g ...

  5. Python学习day07 - Python进阶(1) 内置方法

    figure:last-child { margin-bottom: 0.5rem; } #write ol, #write ul { position: relative; } img { max- ...

  6. python面向对象 : 反射和内置方法

    一. 反射 1. isinstance()和issubclass() isinstance( 对象名, 类名) : 判断对象所属关系,包括父类  (注:type(对象名) is 类名 : 判断对象所属 ...

  7. python 面向对象反射以及内置方法

    一.反射 什么是反射:可以用字符串的方式去访问对象的属性,调用对象的方法(但是不能去访问方法),python中一切皆对象,都可以使用放射. 反射的四种方法: hasattr:hasattr(objec ...

  8. Python面向对象编程及内置方法

    在程序开发中,要设计一个类,通常需要满足以下三个要求: [1]类名 这类事物的名字,满足大驼峰命名法 [2]属性 这类事物具有什么样的特征 [3]方法 这类事物具有什么样的行为 定义简单的类: 定义只 ...

  9. day26.面向对象-反射封装内置方法

    封装 隐藏对象的属性和实现细节,近对外提供公共访问方式 广义:代码保护,面向对象思想 狭义:将属性,方法隐藏起来 class Person: __key = 123456 # 私有的静态属性 def ...

随机推荐

  1. PTA (Advanced Level) 1028 List Sorting

    List Sorting Excel can sort records according to any column. Now you are supposed to imitate this fu ...

  2. ES6 笔记(二)- 总结

        在最近进行的项目中,已经全面使用到ES6,这里对ES6进行整理总结.用得比较多的是带*的内容,这些语法.新增类型.模块调用等从代码量上.可读性上.操作上给项目带来了不少便利.   1.语法 1 ...

  3. [转]Global exception handling in Web API 2.1 and NLog

    本文转自:https://stackoverflow.com/questions/25865610/global-exception-handling-in-web-api-2-1-and-nlog ...

  4. 消息队列系列(二):.Rabbitmq的使用及Web监控工具使用

    一.文档资料        1.官方网站:http://www.rabbitmq.com/        2.安装教程:http://www.rabbitmq.com/install-windows. ...

  5. spring下redis使用资料

    参考资料地址: spring集成redis Spring缓存注解@Cacheable.@CacheEvict.@CachePut使用 redis常用命令 redis持久化(RDB与AOF) Redis ...

  6. 【JavaScript 从零开始】 语言核心部分----可选的分号

    Node.js很是火爆,前段待遇好的飞起.... 于是我决定.... 重头开始学习JavaScript有些比较特别的,或者之前我们注意到,再或者容易出错东西我会记录下来. 可选的分号 和其他许多编程语 ...

  7. @valid注解

    今天发现一个非常好用的注解直接上代码: 实体类domain: @Column(name = "NAME") @NotNull @Size(min = 2,max = 50) pri ...

  8. mysql安装配置、主从复制配置详解

    作者:NiceCui 本文谢绝转载,如需转载需征得作者本人同意,谢谢. 本文链接:http://www.cnblogs.com/NiceCui/p/8213723.html 邮箱:moyi@moyib ...

  9. 翻译 – CSS3 Backgrounds相关介绍——张鑫旭

    —————以下为翻译内容—————- CSS2.1中有5个background属性可以用来控制元素的背景.这5个属性是: background-color background-image backg ...

  10. 客户端ajax请求为实现Token验证添加headers后导致正常请求变为options跨域请求解决方法

    客户端为了实现token认证,通过Jquery的ajaxSetup方法全局配置headers: 全局配置headers后会导致部分不需要token认证的请求变为options请求,导致跨域访问.报错信 ...