Python wrapper causes redundant function calls
I have a function that downloads a file from a given url and, is called from a higher level function, i.e. main().
from requests import get
...
def download_file(url):
response = get(url)
...
<error checks on response>
...
# if no error, write response to file
...
file.write(response)
def main(url):
...
download_file(url)
However, I realized that I should place all the error checks for the response object outside the download_file function. So, I tried wrapping the download_file function so that all the error checks happen outside it.
def check_errors(func):
def check_and_download(url):
response = get(url)
...
<error checks on response>
...
return func(url) # <- I have to call response = get(url) again. That's bad
return check_and_download
As you can see, that wrapper causes the response to get called twice. Once outside the func, and once inside it. That's just redundant. I'm trying to figure out a way that will allow me to call response only once and download the file while having the error checks outside the download_file function.
I feel like this should be a common problem for beginners, but couldn't find relevant questions here. Any suggestions on how to properly deal with this?
PS: One approach I took was to modify the download_file function to accept a response object instead or a url, so that the wrapper could pass an error-checked response object to it. However, the problem then is that the download_file function must be called with a response object in main(). Which would require me to check the response object for errors in main() instead of the wrapper.
python-3.x python-requests wrapper urllib3
add a comment |
I have a function that downloads a file from a given url and, is called from a higher level function, i.e. main().
from requests import get
...
def download_file(url):
response = get(url)
...
<error checks on response>
...
# if no error, write response to file
...
file.write(response)
def main(url):
...
download_file(url)
However, I realized that I should place all the error checks for the response object outside the download_file function. So, I tried wrapping the download_file function so that all the error checks happen outside it.
def check_errors(func):
def check_and_download(url):
response = get(url)
...
<error checks on response>
...
return func(url) # <- I have to call response = get(url) again. That's bad
return check_and_download
As you can see, that wrapper causes the response to get called twice. Once outside the func, and once inside it. That's just redundant. I'm trying to figure out a way that will allow me to call response only once and download the file while having the error checks outside the download_file function.
I feel like this should be a common problem for beginners, but couldn't find relevant questions here. Any suggestions on how to properly deal with this?
PS: One approach I took was to modify the download_file function to accept a response object instead or a url, so that the wrapper could pass an error-checked response object to it. However, the problem then is that the download_file function must be called with a response object in main(). Which would require me to check the response object for errors in main() instead of the wrapper.
python-3.x python-requests wrapper urllib3
My design advice is: don't catch an exception just to raise another exception. If you can't handle the error, then leaving the original exception and traceback intact is generally more useful.
– wim
Nov 28 '18 at 22:02
@wim I know, I didn't do that in my actual code (wrote a comment). it's just for simplicity while explaining. i'll edit my snippet to remove the confusion
– babrar
Nov 28 '18 at 22:03
Then I think the MCVE is not good. Whether you want to re-raise or handle error fromrequests.getis an important high-level question that shouldn't be glossed over.
– wim
Nov 28 '18 at 22:05
@wim maderequest.geterror checks more abstract
– babrar
Nov 28 '18 at 22:21
add a comment |
I have a function that downloads a file from a given url and, is called from a higher level function, i.e. main().
from requests import get
...
def download_file(url):
response = get(url)
...
<error checks on response>
...
# if no error, write response to file
...
file.write(response)
def main(url):
...
download_file(url)
However, I realized that I should place all the error checks for the response object outside the download_file function. So, I tried wrapping the download_file function so that all the error checks happen outside it.
def check_errors(func):
def check_and_download(url):
response = get(url)
...
<error checks on response>
...
return func(url) # <- I have to call response = get(url) again. That's bad
return check_and_download
As you can see, that wrapper causes the response to get called twice. Once outside the func, and once inside it. That's just redundant. I'm trying to figure out a way that will allow me to call response only once and download the file while having the error checks outside the download_file function.
I feel like this should be a common problem for beginners, but couldn't find relevant questions here. Any suggestions on how to properly deal with this?
PS: One approach I took was to modify the download_file function to accept a response object instead or a url, so that the wrapper could pass an error-checked response object to it. However, the problem then is that the download_file function must be called with a response object in main(). Which would require me to check the response object for errors in main() instead of the wrapper.
python-3.x python-requests wrapper urllib3
I have a function that downloads a file from a given url and, is called from a higher level function, i.e. main().
from requests import get
...
def download_file(url):
response = get(url)
...
<error checks on response>
...
# if no error, write response to file
...
file.write(response)
def main(url):
...
download_file(url)
However, I realized that I should place all the error checks for the response object outside the download_file function. So, I tried wrapping the download_file function so that all the error checks happen outside it.
def check_errors(func):
def check_and_download(url):
response = get(url)
...
<error checks on response>
...
return func(url) # <- I have to call response = get(url) again. That's bad
return check_and_download
As you can see, that wrapper causes the response to get called twice. Once outside the func, and once inside it. That's just redundant. I'm trying to figure out a way that will allow me to call response only once and download the file while having the error checks outside the download_file function.
I feel like this should be a common problem for beginners, but couldn't find relevant questions here. Any suggestions on how to properly deal with this?
PS: One approach I took was to modify the download_file function to accept a response object instead or a url, so that the wrapper could pass an error-checked response object to it. However, the problem then is that the download_file function must be called with a response object in main(). Which would require me to check the response object for errors in main() instead of the wrapper.
python-3.x python-requests wrapper urllib3
python-3.x python-requests wrapper urllib3
edited Nov 28 '18 at 22:21
babrar
asked Nov 28 '18 at 21:58
babrarbabrar
257
257
My design advice is: don't catch an exception just to raise another exception. If you can't handle the error, then leaving the original exception and traceback intact is generally more useful.
– wim
Nov 28 '18 at 22:02
@wim I know, I didn't do that in my actual code (wrote a comment). it's just for simplicity while explaining. i'll edit my snippet to remove the confusion
– babrar
Nov 28 '18 at 22:03
Then I think the MCVE is not good. Whether you want to re-raise or handle error fromrequests.getis an important high-level question that shouldn't be glossed over.
– wim
Nov 28 '18 at 22:05
@wim maderequest.geterror checks more abstract
– babrar
Nov 28 '18 at 22:21
add a comment |
My design advice is: don't catch an exception just to raise another exception. If you can't handle the error, then leaving the original exception and traceback intact is generally more useful.
– wim
Nov 28 '18 at 22:02
@wim I know, I didn't do that in my actual code (wrote a comment). it's just for simplicity while explaining. i'll edit my snippet to remove the confusion
– babrar
Nov 28 '18 at 22:03
Then I think the MCVE is not good. Whether you want to re-raise or handle error fromrequests.getis an important high-level question that shouldn't be glossed over.
– wim
Nov 28 '18 at 22:05
@wim maderequest.geterror checks more abstract
– babrar
Nov 28 '18 at 22:21
My design advice is: don't catch an exception just to raise another exception. If you can't handle the error, then leaving the original exception and traceback intact is generally more useful.
– wim
Nov 28 '18 at 22:02
My design advice is: don't catch an exception just to raise another exception. If you can't handle the error, then leaving the original exception and traceback intact is generally more useful.
– wim
Nov 28 '18 at 22:02
@wim I know, I didn't do that in my actual code (wrote a comment). it's just for simplicity while explaining. i'll edit my snippet to remove the confusion
– babrar
Nov 28 '18 at 22:03
@wim I know, I didn't do that in my actual code (wrote a comment). it's just for simplicity while explaining. i'll edit my snippet to remove the confusion
– babrar
Nov 28 '18 at 22:03
Then I think the MCVE is not good. Whether you want to re-raise or handle error from
requests.get is an important high-level question that shouldn't be glossed over.– wim
Nov 28 '18 at 22:05
Then I think the MCVE is not good. Whether you want to re-raise or handle error from
requests.get is an important high-level question that shouldn't be glossed over.– wim
Nov 28 '18 at 22:05
@wim made
request.get error checks more abstract– babrar
Nov 28 '18 at 22:21
@wim made
request.get error checks more abstract– babrar
Nov 28 '18 at 22:21
add a comment |
0
active
oldest
votes
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53528749%2fpython-wrapper-causes-redundant-function-calls%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53528749%2fpython-wrapper-causes-redundant-function-calls%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown

My design advice is: don't catch an exception just to raise another exception. If you can't handle the error, then leaving the original exception and traceback intact is generally more useful.
– wim
Nov 28 '18 at 22:02
@wim I know, I didn't do that in my actual code (wrote a comment). it's just for simplicity while explaining. i'll edit my snippet to remove the confusion
– babrar
Nov 28 '18 at 22:03
Then I think the MCVE is not good. Whether you want to re-raise or handle error from
requests.getis an important high-level question that shouldn't be glossed over.– wim
Nov 28 '18 at 22:05
@wim made
request.geterror checks more abstract– babrar
Nov 28 '18 at 22:21