假定db1, db2 是shelve对象
if switch_d1_and_db2:
func(db1, db2)
else:
func(db2, db1)
怎么才能改写成:
if switch_d1_and_db2:
db1, db2 = db2, db1 # 错误写法
func(db1, db2)
db1, db2 = db2, db1
肯定是不行的,怎么改写呢
高洛峰2017-04-18 09:18:15
Hello, after studying this problem for a while, I came to the conclusion:
It’s too difficult to do and the syntax you want to use doesn’t match what you want to do
I think there is nothing wrong with using the original method
If you want to achieve the exchange you defined, then I have an alternative that is not too beautiful, you can refer to it
The following is an explanation of the above three points:
For the first point, you want:
db1, db2 = db2, db1
No matter what kind of object db1
, db2
is here, the meaning of this exchange is
Let
db1
這個變數參考到原本db2
所參考的 object, 並讓db2
這個變數參考到原本db1
be the object referenced.
But what you want to do is:
Let
db1
這個 file 和db2
swap the contents of this file
Think about it carefully, these two things are not the same. To put it another way, db1, db2 = db2, db1
, it will only make the things referenced by the variables interchange (the variable names are not equal to the file names of the db), but the contents of each file are still not interchangeable. Change.
So using this syntax to interchange is not consistent with the effect you want to achieve.
I won’t elaborate on the second point because it’s reasonable, but you may not like it.
The third point is that I gave a less beautiful alternative, which is to simply define a shelf
的代理類 ShelfProxy
, 這個類盡量模擬 Shelf
類的行為(僅是介面上相似), 並且重載了運算符 ^
defined as exchange:
import shelve
class ShelfProxy:
def __init__(self, *args, **kwargs):
self.args = args
self.kwargs = kwargs
self.file = args[0]
self.loaddb()
@classmethod
def open(cls, *args, **kwargs):
return cls(*args, **kwargs)
def __getattr__(self, name):
return getattr(self.dic, name)
def __setitem__(self, name, value):
self.dic[name] = value
def __getitem__(self, name):
return self.dic[name]
def __xor__(self, other):
self.dic, other.dic = other.dic, self.dic
return True
def __str__(self):
return str(self.dic)
def loaddb(self):
db = shelve.open(*self.args, **self.kwargs)
self.dic = dict(db.items())
db.close()
def close(self):
newdb = shelve.open(self.file, *self.args[1:], **self.kwargs)
for key in newdb.keys():
del newdb[key]
for key, value in self.dic.items():
newdb[key] = value
newdb.close()
I define ^
as ^
定義為 內容上的交換, 之所以選 ^
exchange of content
^
is just because I can’t think of a more suitable symbol. Generally speaking, overloading will not be done like this. And it is unlikely to return instances of other classes, but for convenience and because you want a simple interface, I came up with this strategy. Then we define some test functions:
def define():
db1 = ShelfProxy.open('db1', writeback=True)
db2 = ShelfProxy.open('db2', writeback=True)
db1['name'] = 'db1'
db2['name'] = 'db2'
db1.close()
db2.close()
def check():
db1 = ShelfProxy.open('db1', writeback=True)
db2 = ShelfProxy.open('db2', writeback=True)
print('db1:', db1)
print('db2:', db2)
db1.close()
db2.close()
def switch():
print('switch')
db1 = ShelfProxy.open('db1', writeback=True)
db2 = ShelfProxy.open('db2', writeback=True)
db1 ^ db2
db1.close()
db2.close()
Test code:
if __name__ == '__main__':
define()
check()
switch()
check()
Result:db1: {'name': 'db1'}
db2: {'name': 'db2'}
switch
db1: {'name': 'db2'}
db2: {'name': 'db1'}
Shelf
相同的介面來操作 ShelfProxy
Most of the time, you can use
Questions I answered
: Python-QA🎜