假定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 肯定是不行的,怎么改写呢
db1, db2 = db2, db1
学习是最好的投资!
你好, 我研究这个问题一阵之后结论是:
太难做到而且你想要使用的语法跟你要做的事情并不 match
我觉得用原本的方法没有什么不好
如果你想要做到你定义的这种交换, 那我有一个不算是太漂亮的替代方案, 你可以参考
以下针对上述三点说明:
对于第一点, 你想要:
这边不论 db1, db2 是哪种 object, 这种交换式的意义在于db1, db2 是哪種 object, 這種交換式的意義在於
db1
db2
讓 db1 這個變數參考到原本 db2 所參考的 object, 並讓 db2 這個變數參考到原本 db1 所參考到的 object。
但是你想要做的事情是:
讓 db1 這個 file 和 db2 這個 file 的內容互換
仔細想一想, 這兩件事情並不相同, 換個方式來說, db1, db2 = db2, db1, 只會讓變數參考的東西互換(變數名稱不等於 db 的 file 名稱), 但是每個文件的內容還是沒有互換。
所以 使用這種語法來互換跟你要達到的效果並不一致。
第二點就不多說明了, 因為合理, 只是你可能不喜歡。
第三點我給了一個不怎麼漂亮的替代方案, 就是簡單定義一個 shelf 的代理類 ShelfProxy, 這個類盡量模擬 Shelf 類的行為(僅是介面上相似), 並且重載了運算符 ^ 定義為交換:
shelf
ShelfProxy
Shelf
^
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()
我將 ^ 定義為 內容上的交換, 之所以選 ^ 只是因為我想不到比較適合的符號, 一般來說重載不會這樣進行, 而且也不太會返回其他類的實例, 不過我這邊為求方便且針對你想要一個簡單介面這一點, 出此下策。
接著我們定義一些測試的 function:
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()
測試代碼:
if __name__ == '__main__': define() check() switch() check()
結果:
db1: {'name': 'db1'} db2: {'name': 'db2'} switch db1: {'name': 'db2'} db2: {'name': 'db1'}
大部分的時候, 你可以用跟 Shelf 相同的介面來操作 ShelfProxy
让db1 这个变数参考到原本db2 所参考的object, 并让db2 这个变数参考到原本db1 所参考到的object。
但是你想要做的事情是: 让 db1 这个 file 和 db2 这个 file 的内容互换
你好, 我研究这个问题一阵之后结论是:
太难做到而且你想要使用的语法跟你要做的事情并不 match
我觉得用原本的方法没有什么不好
如果你想要做到你定义的这种交换, 那我有一个不算是太漂亮的替代方案, 你可以参考
以下针对上述三点说明:
对于第一点, 你想要:
这边不论
db1
,db2
是哪种 object, 这种交换式的意义在于db1
,db2
是哪種 object, 這種交換式的意義在於但是你想要做的事情是:
仔細想一想, 這兩件事情並不相同, 換個方式來說,
db1, db2 = db2, db1
, 只會讓變數參考的東西互換(變數名稱不等於 db 的 file 名稱), 但是每個文件的內容還是沒有互換。所以 使用這種語法來互換跟你要達到的效果並不一致。
第二點就不多說明了, 因為合理, 只是你可能不喜歡。
第三點我給了一個不怎麼漂亮的替代方案, 就是簡單定義一個
shelf
的代理類ShelfProxy
, 這個類盡量模擬Shelf
類的行為(僅是介面上相似), 並且重載了運算符^
定義為交換:我將
^
定義為 內容上的交換, 之所以選^
只是因為我想不到比較適合的符號, 一般來說重載不會這樣進行, 而且也不太會返回其他類的實例, 不過我這邊為求方便且針對你想要一個簡單介面這一點, 出此下策。接著我們定義一些測試的 function:
測試代碼:
結果:
結論
大部分的時候, 你可以用跟
Shelf
相同的介面來操作ShelfProxy
但是你想要做的事情是: 让
🎜仔细想一想, 这两件事情并不相同, 换个方式来说,db1
这个 file 和db2
这个 file 的内容互换db1, db2 = db2, db1
, 只会让变数参考的东西互换(变数名称不等于db 的file名称), 但是每个文件的内容还是没有互换。 🎜 🎜所以 🎜使用这种语法来互换跟你要达到的效果并不一致🎜。 🎜 🎜第二点就不多说明了, 因为合理, 只是你可能不喜欢。 🎜 🎜第三点我给了一个不怎么漂亮的替代方案, 就是简单定义一个shelf
的代理类ShelfProxy
, 这个类尽量模拟Shelf
类的行为(仅是介面上相似), 并且重载了运算符^
定义为交换:🎜 rrreee 🎜我将^
定义为🎜内容上的交换🎜, 之所以选^
只是因为我想不到比较适合的符号, 一般来说重载不会这样进行,而且也不太会返回其他类的实例, 不过我这边为求方便且针对你想要一个简单介面这一点, 出此下策。 🎜 🎜接着我们定义一些测试的 function:🎜 rrreee 🎜测试代码:🎜 rrreee 🎜结果:🎜 rrreee结论
🎜大部分的时候, 你可以用跟Shelf
相同的介面来操作ShelfProxy
, 整体效果也类似, 但是你不觉得写了那么多, 还是使用一开始的方法比较简单吗XD🎜 🎜 🎜🎜我回答过的问题🎜: Python-QA🎜