python self 序列_python – `self [key] = value`的魔术方法?

对于赋值=对序列类型,有一个Python魔术方法__setitem__.在容器级别是否有增强赋值的神奇方法?该操作似乎优雅地分解为项类型的扩充分配.这是合乎逻辑的.但是对于其他几乎所有东西都有一种神奇的方法,我认为在序列类型上应该有一组这些运算符的方法.我错过了吗?

该应用程序是一种数据库.考虑使用SELECT实现__getitem__,使用INSERT实现__setitem__. UPDATE应该有类似__additem__等的东西,对吧?

from __future__ import print_function

class Item(object):

def __init__(self, value):

self.value = value

def __str__(self):

return "Item " + str(self.value)

def __iadd__(self, other):

print("Item iadd", self, other)

return Item(self.value + "+" + other.value)

class Container(object):

def __getitem__(self, key):

print("Container getitem", key)

return Item(key)

def __setitem__(self, key, value):

print("Container setitem", key, value)

return self

def __additem__(self, key, value):

print("Container additem would be nice", key, value)

return self

这是SELECT:

>>> c = Container()

>>> _ = c['key']

Container getitem key

这是INSERT:

>>> c['key'] = Item('other')

Container setitem key Item other

如何实施UPDATE?无需分解为SELECT和INSERT:

>>> c['key'] += Item('other')

Container getitem key

Item iadd Item key Item other

Container setitem key Item key+other

那么有没有一种方法可以实现增强分配而不是分解步骤?不将所有行为放在Item类中?

A related question显示了self [key] = value的反编译

解决方法:

不,没有神奇的__additem__方法.

c [k] = v变为魔法方法调用:c .__ setitem __(c .__ getitem __(k).__ iadd __(v)).

包含__setitem__调用是因为并非所有Python对象都支持就地添加.不可变对象(如int和float)不会,因此__add__将被调用而不是__iadd__(并且__add__必须返回一个新值).

我认为你可以按照自己的方式使数据库工作的唯一方法是编写__getitem__,使其返回一个特殊的“项目代理”类型.代理最初不会做任何事情(它没有自己的行为).但是,当在其上查找属性或方法(或调用__magic__方法)时,它将执行必要的数据库操作以使其工作.对于大多数方法和属性查找,它需要查询数据库以获取实际数据,然后返回适当的方法或值.如果它是一个已知的就地修改方法(如append或__iadd__,它可以改为执行不同的数据库操作(如UPDATE而不是SELECT).

编写这样的代理类型并不是很容易,但也不是很荒谬.如果你想要处理许多类型的对象,那么就会有很多角落要覆盖.根据数据库可以容纳的类型集的范围有多窄,可能会缩小您需要将代理复制到少数几个的方法和属性列表(例如算术和比较运算符,如果你有__int__和__float__)只需要支持数字类型).

另一方面,当您只使用较少的代码执行SELECT和INSERT时,您可能会发现不值得开发工作.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值