背景: 頻繁に使用されるデータベース接続を開く関数があるとします。基本的には次のようなものですが、追加の機能があります。
import getpass
import MySQLdb
def myspecialconnect(user='foo', host='bar', port=80085):
password = getpass.getpassword('Enter your password: ')
return MySQLdb.connect(user, password, host, port)
また、場合によっては、次のように 2 つの接続を開きたいことがあります。
read_connection = myspecialconnect()
write_connection = myspecialconnect()
なんという苦痛 - 私はパスワードを 2 回入力しなければなりません。もちろん、これを回避するためにこの 1 つの例を変更する方法はたくさんあります。この1つの機能。しかし、この特殊なケースにより、より一般的なアプリケーションについて考えるようになりました。myspecialconnect(multi=True)
myspecialconnect(copies=9)
質問: 任意の関数からこの機能 (必要なものの複数のコピーを返す) を取得できるようにしたい場合はどうすればよいですか? うーん、これは難しいかもしれません。
まず、うまくいかないことを確認するために、これを試しました:
def doubled(function):
def Wrapper(*args, **kwargs):
return (function(*args, **kwargs),function(*args, **kwargs))
return Wrapper
ユーザー入力を必要としない関数の場合は問題ありません。そうしないと、そこに座ってまったく同じことを 2 回続けて入力する必要があります。これは簡単に修正できますが、ここまでで、これがどこに向かっているのかを確認できるかもしれません。
def doubled(function):
def Wrapper(*args, **kwargs):
result = function(*args, **kwargs)
return (result, result)
return Wrapper
このバージョンは、ユーザー入力を 1 回だけ受け取りますが、同じ参照を 2 回返すため、必要以上に複雑な方法になっていますfoo = bar = object()
。「あはは!」copy
「モジュールを調べたほうがいいかもしれません」と私は言います。これは私がやったことですが、それがどのように機能するかはまだよくわかりません...
>>> import copy
>>> a = (i for i in [1,2])
>>> a
<generator object <genexpr> at 0x03FB0878>
>>> copy.copy(a)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\WinPython-32bit-2.7.5.1\python-2.7.5\lib\copy.py", line 96, in copy
return _reconstruct(x, rv, 0)
File "C:\WinPython-32bit-2.7.5.1\python-2.7.5\lib\copy.py", line 329, in _reconstruct
y = callable(*args)
File "C:\WinPython-32bit-2.7.5.1\python-2.7.5\lib\copy_reg.py", line 93, in __newobj__
return cls.__new__(cls, *args)
TypeError: object.__new__(generator) is not safe, use generator.__new__()
>>> copy.deepcopy(a)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\WinPython-32bit-2.7.5.1\python-2.7.5\lib\copy.py", line 190, in deepcopy
y = _reconstruct(x, rv, 1, memo)
File "C:\WinPython-32bit-2.7.5.1\python-2.7.5\lib\copy.py", line 329, in _reconstruct
y = callable(*args)
File "C:\WinPython-32bit-2.7.5.1\python-2.7.5\lib\copy_reg.py", line 93, in __newobj__
return cls.__new__(cls, *args)
TypeError: object.__new__(generator) is not safe, use generator.__new__()
もちろん、これまでに、この小さな副次的な問題に正当化できる限り (またはそれ以上) の時間を費やしてきました。つまり、非常に興味があります。これは、何十ものケースをそれぞれ独自の特別な方法で明示的に処理することを余儀なくされたモンスターに変わることなく、任意のインスタンスのコピーを返す方法で行うことができますか?