__getitem__,__setitem__和__delitem__

  实现了对象属性的字典化操作。

class Person:
def __init__(self, name, age, hobby):
self.name = name
self.age = age
self.hobby = hobby def __getitem__(self, item):
if hasattr(self, item):
return self.__dict__[item] def __setitem__(self, key, value):
self.__dict__[key] = value def __delitem__(self, key):
del self.__dict__[key] zxc = Person('zxc', 26, 'read')
print(zxc.name) # zxc 对象原生查看属性的方法
print(zxc['name']) # zxc 通过getitem实现的查看方法
zxc['name'] = 'zzy' # 通过setitem实现修改
zxc['weight'] = 70 # 通过setitem实现增加
print(zxc.__dict__) # {'weight': 70, 'name': 'zzy', 'hobby': 'read', 'age': 26}
del zxc['hobby'] # 通过delitem实现删除
print(zxc.__dict__) # {'name': 'zzy', 'weight': 70, 'age': 26}

  __new__:构造方法:创建一个对象

  实例化要用到__new__方法

class Foo:
def __init__(self, name):
self.name = name def __new__(cls, *args, **kwargs):
return '创建一个对象' obj = Foo('zxc') # 当实例化一个对象的时候,调用的就是__new__方法。
print(obj) # 打印:创建一个对象
class Foo:
def __init__(self, name):
self.name = name def __new__(cls, *args, **kwargs):
return object.__new__(Foo) # object里面的__new__方法用来构造对象 obj = Foo('zxc')
print(obj) # <__main__.Foo object at 0x000002CADD5C0048>

  __new__方法的使用:单例模式

  一种程序设计模式:一个类始终只有一个实例

class Foo:
__instance = False def __init__(self, name, age):
self.name = name
self.age = age def __new__(cls, *args, **kwargs):
if cls.__instance: # 当实例化一个对象之后,后面的实例化就使用之前的对象
return cls.__instance
cls.__instance = object.__new__(cls)
return cls.__instance a = Foo('zxc', 25)
b = Foo('zxf', 22)
print(a.__dict__) # {'name': 'zxf', 'age': 22}
print(b.__dict__) # {'name': 'zxf', 'age': 22}
b.hobby = 'read'
print(a.hobby) # read
# a和b是同一个对象

  __eq__和__hash__

class Foo:
def __init__(self, name):
self.name = name a = Foo('zxc')
b = Foo('zxc')
print(a == b) # False 正常一个类的两个对象即使属性一样他还是不同的 class Foo:
def __init__(self, name):
self.name = name def __eq__(self, other):
if self.name == other.name:
return True
else:
return False a = Foo('zxc')
b = Foo('zxc')
print(a) # <__main__.Foo object at 0x000001543BA60048>
print(b) # <__main__.Foo object at 0x000001543BA604E0>
print(a == b) # True a和b并不相同,但结果却是True,说明==比较时调用的就是__eq__方法,默认使用的都是object的__eq__方法
class Foo:
def __hash__(self):
return 10 a = Foo()
print(hash(a)) # 10 内置函数hash调用的就是对象的__hash__方法

  set会依赖__eq__和__hash__

class Foo:
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
else:
return False a = Foo('zxc', 25, '男')
b = Foo('zxc', 24, '男')
print(set([a, b])) # {<__main__.Foo object at 0x000002BFB7FC04E0>}
# 当name和sex相同时,a和b被认为是同一个,set后去重 # 注释掉类里的__hash__方法
print(set([a, b])) # 报错 显示类Foo不能哈希 说明set依赖对象的__hash__方法 # 注释掉类里的__eq__方法
print(set([a, b])) # 结果还是两个元素 并没有去重 说明set的去重还依赖对象的__eq__方法返回结果

  __len__

class Foo:
def __len__(self):
return 10 a = Foo()
print(len(a)) # 10 内置函数len调用的就是对象的__len__方法,默认使用的都是object的__len__方法

python类中的双下划线方法的更多相关文章

  1. python面向对象双下划线方法与元类

    目录 双下划线方法(__) 元类简介 产生类的两种表现形式 元类的基本使用 元类进阶操作 __new__方法 双下划线方法(__) 面向对象中的双下方法也有一些人称之为是魔法方法,有些双下方法不需要刻 ...

  2. python中那些双下划线开头得函数和变量--转载

    Python中下划线---完全解读     Python 用下划线作为变量前缀和后缀指定特殊变量 _xxx 不能用'from module import *'导入 __xxx__ 系统定义名字 __x ...

  3. python python中那些双下划线开头的那些函数都是干啥用用的

    1.写在前面 今天遇到了__slots__,,所以我就想了解下python中那些双下划线开头的那些函数都是干啥用用的,翻到了下面这篇博客,看着很全面,我只了解其中的一部分,还不敢乱下定义. 其实如果足 ...

  4. python中那些双下划线开头得函数和变量

    Python中下划线---完全解读     Python 用下划线作为变量前缀和后缀指定特殊变量 _xxx 不能用’from module import *’导入 __xxx__ 系统定义名字 __x ...

  5. Python - 面向对象编程 - 魔术方法(双下划线方法)

    什么是魔术方法 在Python中,所有以 __ 双下划线包起来的方法,都统称为 Magic Method 魔术方法,也叫双下划线方法 有哪些重要的魔术方法? __new__ https://www.c ...

  6. 测试Python类成员的单下划线,双下划线,两头下划线的区别

    首先原谅一个菜鸟叫他“两头下划线”.记得在windows编程中,很多宏定义使用下划线+大写,给人逼格很高的错觉.对于Python下划线的认识,大概是从__dict__这个属性开始的,看__dict__ ...

  7. Python: 类中为什么要定义__init__()方法

    学习并转自:https://blog.csdn.net/geerniya/article/details/77487941 1. 不用init()方法定义类 定义一个矩形的类,目的是求周长和面积. c ...

  8. python类中的__init__和__new__方法

    Python中类: Python中在创建类的过程中最先调用的不是__init__方法而是__new__方法,__new__方法是一个静态方法,在创建一个类对象时其实是通过__new__方法首先创建出一 ...

  9. Python中被双下划线包围的魔法方法

    基本的魔法方法 __new__(cls[, ...]) 用来创建对象 1. __new__ 是在一个对象实例化的时候所调用的第一个方法 2. 它的第一个参数是这个类,其他的参数是用来直接传递给 __i ...

随机推荐

  1. Python 运算符首尾匹配

  2. JQuery--关系选择器

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. MySQL数据库操作语句(cmd环境运行)

    一.开启MySQL服务器 1,  通过windows提供的服务管理器来完成 windows键+R 输入: services.msc 2.在本地服务中打开其服务 3.在DOC命令行下 net stop ...

  4. sping,springMVC @Component 注解的对象都是单例模式,变量不能全局

    错误方式:      将属性和变量定义为全局,单例模式,所有人共享,导致所有人的数据都发生错误! 正确方式 一:    将变量定义到局部,互不影响. 正确方式 二:      假如必须放到全局所有方法 ...

  5. Java 和 DynamoDB

    https://docs.aws.amazon.com/zh_cn/amazondynamodb/latest/developerguide/GettingStarted.Java.html 官方

  6. oracle如何检查用户是否用了默认密码

    如果使用默认密码,很可能就对你的数据库造成一定的安全隐患,那么可以使用如下的查询获得那些用户使用默认密码 select username "User(s) with Default Pass ...

  7. python中defaultdict类

    回宿舍前翻翻Codeforces的时候发现了一个有趣的代码..其实是我没这么用过 :D 这是一份417B的代码 import sys from collections import defaultdi ...

  8. 2018-11-3-WPF-内部的5个窗口之-MediaContextNotificationWindow

    title author date CreateTime categories WPF 内部的5个窗口之 MediaContextNotificationWindow lindexi 2018-11- ...

  9. linux中$@,$*,$0,$$,$?参数的含义

    $# 是传给脚本的参数个数 $ 是脚本本身的名字 $ 是传递给该shell脚本的第一个参数 $ 是传递给该shell脚本的第二个参数 $@ 是传给脚本的所有参数的列表 $* 是以一个单字符串显示所有向 ...

  10. 25-3 requests模块的cookie和代理操作

    一.基于requests模块的cookie操作 引言:有些时候,我们在使用爬虫程序去爬取一些用户相关信息的数据(爬取张三“人人网”个人主页数据)时,如果使用之前requests模块常规操作时,往往达不 ...