编程语言
首页 > 编程语言> > 【python 9】python 魔术方法

【python 9】python 魔术方法

作者:互联网

文章目录


python 中以 “__” 开头和结尾的成员,都被称为类的特殊成员(特殊属性和方法)。

python 中的

一、__getitem__ 获取属性

在字典和列表中,我们经常会用到 [] 来获取对应元素,因为字典和列表中都内置了 __getitem__ 方法。

"__getitem__" in (dir(list))
>>>
True
"__getitem__" in (dir(dict))
>>>
True

__getitem__ 的作用:

当定义了一个类的时候,当该类的实例化对象通过 [] 来取值的时候,会调用 __getitem__ 方法,也就是说这个方法能够返回与指定键相关联的值

使用 [] 对对象中的属性进行取值、赋值或删除时,会自动触发对应的 __getitem____setitem____delitem__ 方法

class DataBase:
    def __init__(self,id,address):
        #初始化方法
        self.id=id
        self.address=address
        self.d={self.id:1,self.address:"192.168.1.1"}

    def __getitem__(self,key):
        return self.d.get(key,"default")

data=DataBase(1,"192.168.1.1")
print(data['hi'])         # output default
print(data[data.id])      # output 1
print(data[data.address]) # output 192.168.1.1
print(data[1])            # output 1
class Person(object):
    def __init__(self, info):
        self.info = info
    def __getitem__(self, key):
        print('__getitem__:', key)
        return self.info[key]
person_info = {'xiaowang': 1, 'xiaoming': 2, 'xiaohong': 3}
person = Person(person_info)
print(person['xiaoming'])
>>>
__getitem__: xiaoming
2

如果没有定义 __getitem__ 但使用 [] 来取属性的话,则会报错:

class Person(object):
    def __init__(self, info):
        self.info = info
person_info = {'xiaowang': 1, 'xiaoming': 2, 'xiaohong': 3}
person = Person(person_info)
print(person['xiaoming'])
>>>
TypeError: 'Person' object is not subscriptable

二、__setitem__ 设置属性

__setitem__ 可以设置属性,可以新增,也可以修改现有的

class Person(object):
    def __init__(self, info):
        self.info = info
    def __setitem__(self, key, value):
        print('__setitem__:', key, value)
        self.info[key] = value
person_info = {'xiaowang': 1, 'xiaoming': 2, 'xiaohong': 3}
person = Person(person_info)

###### 2、修改
person['xiaobai'] = 4
print('person_info after change:', person_info)
>>>
__setitem__: xiaobai 4
person_info after change: {'xiaowang': 1, 'xiaoming': 2, 'xiaohong': 3, 'xiaobai': 4}
class Person(object):
    def __init__(self, info):
        self.info = info
    def __setitem__(self, key, value):
        print('__setitem__:', key, value)
        self.info[key] = value
person_info = {'xiaowang': 1, 'xiaoming': 2, 'xiaohong': 3}
person = Person(person_info)

###### 2、修改
person['xiaowang'] = 5
print('person_info after change:', person_info)
>>>
__setitem__: xiaowang 5
person_info after change: {'xiaowang': 5, 'xiaoming': 2, 'xiaohong': 3}

三、__delitem__ 删除属性

class Person(object):
    def __init__(self, info):
        self.info = info
    def __delitem__(self, key):
        print('__delitem__:', key)
        del self.info[key]
    def __len__(self):
        return len(self.info)
person_info = {'xiaowang': 1, 'xiaoming': 2, 'xiaohong': 3}
person = Person(person_info)
###### 3、删除
del person['xiaoming']
print('person_info after del:', person_info)
>>>
__delitem__: xiaoming
person_info after del: {'xiaowang': 1, 'xiaohong': 3}

四、__len__ 求长度

class Person(object):
    def __init__(self, info):
        self.info = info
    def __len__(self):
        return len(self.info)
person_info = {'xiaowang': 1, 'xiaoming': 2, 'xiaohong': 3}
person = Person(person_info)
###### 4、求长度
print('final len of info:', len(person_info))
>>>
final len of info: 3

总体代码:

class Person(object):
    def __init__(self, info):
        self.info = info
    def __getitem__(self, key):
        print('__getitem__:', key)
        return self.info[key]
    def __setitem__(self, key, value):
        print('__setitem__:', key, value)
        self.info[key] = value
    def __delitem__(self, key):
        print('__delitem__:', key)
        del self.info[key]
    def __len__(self):
        return len(self.info)
person_info = {'xiaowang': 1, 'xiaoming': 2, 'xiaohong': 3}
person = Person(person_info)
###### 1、获取
print('xiaoming:', person['xiaoming']) 
>>>
__getitem__: xiaoming
xiaoming: 2

###### 2、修改
person['xiaobai'] = 4
print('person_info after change:', person_info)
>>>
__setitem__: xiaobai 4
person_info after change: {'xiaowang': 1, 'xiaoming': 2, 'xiaohong': 3, 'xiaobai': 4}

###### 3、删除
del person['xiaoming']
print('person_info after del:', person_info)
>>>
__delitem__: xiaoming
person_info after del: {'xiaowang': 1, 'xiaohong': 3, 'xiaobai': 4}

###### 4、求长度
print('final len of info:', len(person_info))
>>>
final len of info: 3

五、__call__ 将类变成一个可调用的函数

__call__ 的本质其实是将一个类变成一个函数,使得这个类的实例可以像函数一样调用

python 中,凡是可以将 () 直接应用到自身并执行,都称为“可调用对象”,可调用对象包括自定义函数、python 内置函数、以及类实例对象(即有 call 的类)

对于可调用对象,名称() 可以理解为 名称.__call__() 的简写,

class Test(object):
    def __init__(self, name):
        self.name = name
    def __call__(self):
        print('here is in __call__!')
        print('my name is {}'.format(self.name))
test = Test('xiaowang')
test()
>>>
here is in __call__!
my name is xiaowang

当类中没写 __call__ 的时候:

class Test(object):
    def __init__(self, name):
        self.name = name
test = Test('xiaowang')
test()
>>>
TypeError: 'Test' object is not callable
报错该对象无法调用

标签:info,__,person,python,self,魔术,key,print,方法
来源: https://blog.csdn.net/jiaoyangwm/article/details/120253286