background: let's have function opens frequently-used database connection, following additional bells , whistles:
import getpass import mysqldb def myspecialconnect(user='foo', host='bar', port=80085): password = getpass.getpassword('enter password: ') return mysqldb.connect(user, password, host, port) and maybe sometimes, want open 2 connections, along lines of:
read_connection = myspecialconnect() write_connection = myspecialconnect() what pain - have enter password twice, when want same thing again. of course, there many ways modify 1 example avoid - for example, argument added myspecialconnect(multi=true) return 2 connections instead of one, or myspecialconnect(copies=9) if want crazy, corresponding code make happen inside 1 function. however, special case prompted me wonder more general application.
question: if wanted able functionality (return multiple copies of whatever want) arbitrary function? hmm - tricky.
first, confirm doesn't work, tried this:
def doubled(function): def wrapper(*args, **kwargs): return (function(*args, **kwargs),function(*args, **kwargs)) return wrapper that's okay function requires no user input; otherwise, still have sit there , input exact same thing twice in row. that's easy enough fix, might able see going:
def doubled(function): def wrapper(*args, **kwargs): result = function(*args, **kwargs) return (result, result) return wrapper this version takes user input once, returns same reference twice, making nothing more needlessly convoluted way foo = bar = object(). "aha!" says i, "maybe should take @ copy module." did, don't quite know how works yet...
>>> import copy >>> = (i in [1,2]) >>> <generator object <genexpr> @ 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) 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) not safe, use generator.__new__() of course i've spent time can possibly justify (or more) on little side problem, means i'm incredibly curious. can done in way returns copies of arbitrary instances, without turning monster forced explicitly handle dozens of cases, each in own special way?
there's no general way want. it'd simple if wanted replay first function call - first try would've worked. unfortunately, requirement replay user input complicates things.
first, don't want copy. how copy database connection? there's state on over other side of network connection you'd have duplicate, , you'd have pick new ports, , wouldn't end being copy in sense of having same state , properties. want open new connection same parameters old one.
second, there's no way decorator know inputs replay. calling function twice same arguments easy. calling function twice, replaying user's input first call second call, messy possible. however, if decorator tried replay absolutely input first call second call, end replaying database's tcp responses, too. instead of talking database , setting connection, second call talk decorator , return connection object doesn't work.
instead of trying double myspecialconnect, make function doesn't need read user input , double that. read password once, pass doubled function.
Comments
Post a Comment