Why doesn't del delete it?
up vote
3
down vote
favorite
The code below creates a "tee" object that tees stdout to a file as well as the terminal.
If do del t
as below when I'm done tee-ing, the object doesn't get deleted and the __del__()
member doesn't get called (so the tee-ing continues):
t = tee("foo.txt")
print("bar")
del t
But if I call __del__()
directly, things work fine:
t = tee("foo.txt")
print("bar")
t.__del__()
Why doesn't the del
work? What's the right way to do this?
class tee():
def __init__(self, filepath):
self.old_stdout = sys.stdout
self.old_stderr = sys.stderr
self.name = filepath
sys.stdout = self
sys.stderr = self
def write(self, text):
self.old_stdout.write(text)
with open(self.name, 'a', encoding="utf-8") as f:
f.write(text)
def flush(self):
pass
def __del__(self):
sys.stdout = self.old_stdout
sys.stdout = self.old_stderr
python
add a comment |
up vote
3
down vote
favorite
The code below creates a "tee" object that tees stdout to a file as well as the terminal.
If do del t
as below when I'm done tee-ing, the object doesn't get deleted and the __del__()
member doesn't get called (so the tee-ing continues):
t = tee("foo.txt")
print("bar")
del t
But if I call __del__()
directly, things work fine:
t = tee("foo.txt")
print("bar")
t.__del__()
Why doesn't the del
work? What's the right way to do this?
class tee():
def __init__(self, filepath):
self.old_stdout = sys.stdout
self.old_stderr = sys.stderr
self.name = filepath
sys.stdout = self
sys.stderr = self
def write(self, text):
self.old_stdout.write(text)
with open(self.name, 'a', encoding="utf-8") as f:
f.write(text)
def flush(self):
pass
def __del__(self):
sys.stdout = self.old_stdout
sys.stdout = self.old_stderr
python
5
del
only unbinds the variable name, it does not guarantee that the object gets destroyed immediately, as stated in the docs: docs.python.org/3/reference/datamodel.html#object.__del__
– UnholySheep
Nov 11 at 18:17
add a comment |
up vote
3
down vote
favorite
up vote
3
down vote
favorite
The code below creates a "tee" object that tees stdout to a file as well as the terminal.
If do del t
as below when I'm done tee-ing, the object doesn't get deleted and the __del__()
member doesn't get called (so the tee-ing continues):
t = tee("foo.txt")
print("bar")
del t
But if I call __del__()
directly, things work fine:
t = tee("foo.txt")
print("bar")
t.__del__()
Why doesn't the del
work? What's the right way to do this?
class tee():
def __init__(self, filepath):
self.old_stdout = sys.stdout
self.old_stderr = sys.stderr
self.name = filepath
sys.stdout = self
sys.stderr = self
def write(self, text):
self.old_stdout.write(text)
with open(self.name, 'a', encoding="utf-8") as f:
f.write(text)
def flush(self):
pass
def __del__(self):
sys.stdout = self.old_stdout
sys.stdout = self.old_stderr
python
The code below creates a "tee" object that tees stdout to a file as well as the terminal.
If do del t
as below when I'm done tee-ing, the object doesn't get deleted and the __del__()
member doesn't get called (so the tee-ing continues):
t = tee("foo.txt")
print("bar")
del t
But if I call __del__()
directly, things work fine:
t = tee("foo.txt")
print("bar")
t.__del__()
Why doesn't the del
work? What's the right way to do this?
class tee():
def __init__(self, filepath):
self.old_stdout = sys.stdout
self.old_stderr = sys.stderr
self.name = filepath
sys.stdout = self
sys.stderr = self
def write(self, text):
self.old_stdout.write(text)
with open(self.name, 'a', encoding="utf-8") as f:
f.write(text)
def flush(self):
pass
def __del__(self):
sys.stdout = self.old_stdout
sys.stdout = self.old_stderr
python
python
asked Nov 11 at 18:14
nerdfever.com
703619
703619
5
del
only unbinds the variable name, it does not guarantee that the object gets destroyed immediately, as stated in the docs: docs.python.org/3/reference/datamodel.html#object.__del__
– UnholySheep
Nov 11 at 18:17
add a comment |
5
del
only unbinds the variable name, it does not guarantee that the object gets destroyed immediately, as stated in the docs: docs.python.org/3/reference/datamodel.html#object.__del__
– UnholySheep
Nov 11 at 18:17
5
5
del
only unbinds the variable name, it does not guarantee that the object gets destroyed immediately, as stated in the docs: docs.python.org/3/reference/datamodel.html#object.__del__– UnholySheep
Nov 11 at 18:17
del
only unbinds the variable name, it does not guarantee that the object gets destroyed immediately, as stated in the docs: docs.python.org/3/reference/datamodel.html#object.__del__– UnholySheep
Nov 11 at 18:17
add a comment |
2 Answers
2
active
oldest
votes
up vote
7
down vote
Note
del x
doesn’t directly callx.__del__()
— the former decrements the reference count for x by one, and the latter is only called when x’s reference count reaches zero.
Taken from the data model section of the Python 3 documentation.
You've referenced the class inside the constructor:
sys.stdout = self
sys.stderr = self
The reference will remain and as a result the object will stay “alive”.
But in the code above there's only one reference to 't'. So the refcount should reach zero at 'del t'. No?
– nerdfever.com
Nov 11 at 18:19
@nerdfever.com I assume GC takes care of callingx.__del__
once there are no references exist to it.
– Adam Smith
Nov 11 at 18:21
@nerdfever.com the gc doesn't run after every line or check every variable all the time, that would be too "expensive". It just does its thing every now and then, and has a hierarchy of variables to check reference counts for.
– Paritosh Singh
Nov 11 at 18:24
8
@nerdfever.com: You seem to have forgotten about the two references you stored insys.stdout
andsys.stderr
.
– user2357112
Nov 11 at 18:24
@user2357112 Make than an answer and I'll accept it. (Thanks.)
– nerdfever.com
Nov 11 at 18:25
|
show 3 more comments
up vote
2
down vote
What you’re actually looking for is the with-statement that is used for a specific context. You open the file, do something with it and close it again.
with tree(“foo.txt) as t:
t.write(“bar”)
This will call the exit method in the end.
class tee():
def __init__(self, filepath):
self.old_stdout = sys.stdout
self.old_stderr = sys.stderr
self.name = filepath
sys.stdout = self
sys.stderr = self
def write(self, text):
self.old_stdout.write(text)
with open(self.name, 'a', encoding="utf-8") as f:
f.write(text)
def flush(self):
pass
def __exit__(self):
sys.stdout = self.old_stdout
sys.stdout = self.old_stderr
Actually your class is doing the same thing with the file handler in the write method.
For the delete method: As the others already mentioned, the delete statement will just decrement the reference counter. Once the number of references has reached zero, the object will be garbage collected and the delete method will be invoked. But this won’t happen in your case since the object is still referenced by the standard output.
add a comment |
Your Answer
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',
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%2f53251738%2fwhy-doesnt-del-object-delete-it%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
7
down vote
Note
del x
doesn’t directly callx.__del__()
— the former decrements the reference count for x by one, and the latter is only called when x’s reference count reaches zero.
Taken from the data model section of the Python 3 documentation.
You've referenced the class inside the constructor:
sys.stdout = self
sys.stderr = self
The reference will remain and as a result the object will stay “alive”.
But in the code above there's only one reference to 't'. So the refcount should reach zero at 'del t'. No?
– nerdfever.com
Nov 11 at 18:19
@nerdfever.com I assume GC takes care of callingx.__del__
once there are no references exist to it.
– Adam Smith
Nov 11 at 18:21
@nerdfever.com the gc doesn't run after every line or check every variable all the time, that would be too "expensive". It just does its thing every now and then, and has a hierarchy of variables to check reference counts for.
– Paritosh Singh
Nov 11 at 18:24
8
@nerdfever.com: You seem to have forgotten about the two references you stored insys.stdout
andsys.stderr
.
– user2357112
Nov 11 at 18:24
@user2357112 Make than an answer and I'll accept it. (Thanks.)
– nerdfever.com
Nov 11 at 18:25
|
show 3 more comments
up vote
7
down vote
Note
del x
doesn’t directly callx.__del__()
— the former decrements the reference count for x by one, and the latter is only called when x’s reference count reaches zero.
Taken from the data model section of the Python 3 documentation.
You've referenced the class inside the constructor:
sys.stdout = self
sys.stderr = self
The reference will remain and as a result the object will stay “alive”.
But in the code above there's only one reference to 't'. So the refcount should reach zero at 'del t'. No?
– nerdfever.com
Nov 11 at 18:19
@nerdfever.com I assume GC takes care of callingx.__del__
once there are no references exist to it.
– Adam Smith
Nov 11 at 18:21
@nerdfever.com the gc doesn't run after every line or check every variable all the time, that would be too "expensive". It just does its thing every now and then, and has a hierarchy of variables to check reference counts for.
– Paritosh Singh
Nov 11 at 18:24
8
@nerdfever.com: You seem to have forgotten about the two references you stored insys.stdout
andsys.stderr
.
– user2357112
Nov 11 at 18:24
@user2357112 Make than an answer and I'll accept it. (Thanks.)
– nerdfever.com
Nov 11 at 18:25
|
show 3 more comments
up vote
7
down vote
up vote
7
down vote
Note
del x
doesn’t directly callx.__del__()
— the former decrements the reference count for x by one, and the latter is only called when x’s reference count reaches zero.
Taken from the data model section of the Python 3 documentation.
You've referenced the class inside the constructor:
sys.stdout = self
sys.stderr = self
The reference will remain and as a result the object will stay “alive”.
Note
del x
doesn’t directly callx.__del__()
— the former decrements the reference count for x by one, and the latter is only called when x’s reference count reaches zero.
Taken from the data model section of the Python 3 documentation.
You've referenced the class inside the constructor:
sys.stdout = self
sys.stderr = self
The reference will remain and as a result the object will stay “alive”.
edited Nov 12 at 15:22
asynts
7241720
7241720
answered Nov 11 at 18:18
Liumatt
13215
13215
But in the code above there's only one reference to 't'. So the refcount should reach zero at 'del t'. No?
– nerdfever.com
Nov 11 at 18:19
@nerdfever.com I assume GC takes care of callingx.__del__
once there are no references exist to it.
– Adam Smith
Nov 11 at 18:21
@nerdfever.com the gc doesn't run after every line or check every variable all the time, that would be too "expensive". It just does its thing every now and then, and has a hierarchy of variables to check reference counts for.
– Paritosh Singh
Nov 11 at 18:24
8
@nerdfever.com: You seem to have forgotten about the two references you stored insys.stdout
andsys.stderr
.
– user2357112
Nov 11 at 18:24
@user2357112 Make than an answer and I'll accept it. (Thanks.)
– nerdfever.com
Nov 11 at 18:25
|
show 3 more comments
But in the code above there's only one reference to 't'. So the refcount should reach zero at 'del t'. No?
– nerdfever.com
Nov 11 at 18:19
@nerdfever.com I assume GC takes care of callingx.__del__
once there are no references exist to it.
– Adam Smith
Nov 11 at 18:21
@nerdfever.com the gc doesn't run after every line or check every variable all the time, that would be too "expensive". It just does its thing every now and then, and has a hierarchy of variables to check reference counts for.
– Paritosh Singh
Nov 11 at 18:24
8
@nerdfever.com: You seem to have forgotten about the two references you stored insys.stdout
andsys.stderr
.
– user2357112
Nov 11 at 18:24
@user2357112 Make than an answer and I'll accept it. (Thanks.)
– nerdfever.com
Nov 11 at 18:25
But in the code above there's only one reference to 't'. So the refcount should reach zero at 'del t'. No?
– nerdfever.com
Nov 11 at 18:19
But in the code above there's only one reference to 't'. So the refcount should reach zero at 'del t'. No?
– nerdfever.com
Nov 11 at 18:19
@nerdfever.com I assume GC takes care of calling
x.__del__
once there are no references exist to it.– Adam Smith
Nov 11 at 18:21
@nerdfever.com I assume GC takes care of calling
x.__del__
once there are no references exist to it.– Adam Smith
Nov 11 at 18:21
@nerdfever.com the gc doesn't run after every line or check every variable all the time, that would be too "expensive". It just does its thing every now and then, and has a hierarchy of variables to check reference counts for.
– Paritosh Singh
Nov 11 at 18:24
@nerdfever.com the gc doesn't run after every line or check every variable all the time, that would be too "expensive". It just does its thing every now and then, and has a hierarchy of variables to check reference counts for.
– Paritosh Singh
Nov 11 at 18:24
8
8
@nerdfever.com: You seem to have forgotten about the two references you stored in
sys.stdout
and sys.stderr
.– user2357112
Nov 11 at 18:24
@nerdfever.com: You seem to have forgotten about the two references you stored in
sys.stdout
and sys.stderr
.– user2357112
Nov 11 at 18:24
@user2357112 Make than an answer and I'll accept it. (Thanks.)
– nerdfever.com
Nov 11 at 18:25
@user2357112 Make than an answer and I'll accept it. (Thanks.)
– nerdfever.com
Nov 11 at 18:25
|
show 3 more comments
up vote
2
down vote
What you’re actually looking for is the with-statement that is used for a specific context. You open the file, do something with it and close it again.
with tree(“foo.txt) as t:
t.write(“bar”)
This will call the exit method in the end.
class tee():
def __init__(self, filepath):
self.old_stdout = sys.stdout
self.old_stderr = sys.stderr
self.name = filepath
sys.stdout = self
sys.stderr = self
def write(self, text):
self.old_stdout.write(text)
with open(self.name, 'a', encoding="utf-8") as f:
f.write(text)
def flush(self):
pass
def __exit__(self):
sys.stdout = self.old_stdout
sys.stdout = self.old_stderr
Actually your class is doing the same thing with the file handler in the write method.
For the delete method: As the others already mentioned, the delete statement will just decrement the reference counter. Once the number of references has reached zero, the object will be garbage collected and the delete method will be invoked. But this won’t happen in your case since the object is still referenced by the standard output.
add a comment |
up vote
2
down vote
What you’re actually looking for is the with-statement that is used for a specific context. You open the file, do something with it and close it again.
with tree(“foo.txt) as t:
t.write(“bar”)
This will call the exit method in the end.
class tee():
def __init__(self, filepath):
self.old_stdout = sys.stdout
self.old_stderr = sys.stderr
self.name = filepath
sys.stdout = self
sys.stderr = self
def write(self, text):
self.old_stdout.write(text)
with open(self.name, 'a', encoding="utf-8") as f:
f.write(text)
def flush(self):
pass
def __exit__(self):
sys.stdout = self.old_stdout
sys.stdout = self.old_stderr
Actually your class is doing the same thing with the file handler in the write method.
For the delete method: As the others already mentioned, the delete statement will just decrement the reference counter. Once the number of references has reached zero, the object will be garbage collected and the delete method will be invoked. But this won’t happen in your case since the object is still referenced by the standard output.
add a comment |
up vote
2
down vote
up vote
2
down vote
What you’re actually looking for is the with-statement that is used for a specific context. You open the file, do something with it and close it again.
with tree(“foo.txt) as t:
t.write(“bar”)
This will call the exit method in the end.
class tee():
def __init__(self, filepath):
self.old_stdout = sys.stdout
self.old_stderr = sys.stderr
self.name = filepath
sys.stdout = self
sys.stderr = self
def write(self, text):
self.old_stdout.write(text)
with open(self.name, 'a', encoding="utf-8") as f:
f.write(text)
def flush(self):
pass
def __exit__(self):
sys.stdout = self.old_stdout
sys.stdout = self.old_stderr
Actually your class is doing the same thing with the file handler in the write method.
For the delete method: As the others already mentioned, the delete statement will just decrement the reference counter. Once the number of references has reached zero, the object will be garbage collected and the delete method will be invoked. But this won’t happen in your case since the object is still referenced by the standard output.
What you’re actually looking for is the with-statement that is used for a specific context. You open the file, do something with it and close it again.
with tree(“foo.txt) as t:
t.write(“bar”)
This will call the exit method in the end.
class tee():
def __init__(self, filepath):
self.old_stdout = sys.stdout
self.old_stderr = sys.stderr
self.name = filepath
sys.stdout = self
sys.stderr = self
def write(self, text):
self.old_stdout.write(text)
with open(self.name, 'a', encoding="utf-8") as f:
f.write(text)
def flush(self):
pass
def __exit__(self):
sys.stdout = self.old_stdout
sys.stdout = self.old_stderr
Actually your class is doing the same thing with the file handler in the write method.
For the delete method: As the others already mentioned, the delete statement will just decrement the reference counter. Once the number of references has reached zero, the object will be garbage collected and the delete method will be invoked. But this won’t happen in your case since the object is still referenced by the standard output.
edited Nov 12 at 16:15
answered Nov 11 at 19:46
Matthias
2,18523376
2,18523376
add a comment |
add a comment |
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.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- 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%2f53251738%2fwhy-doesnt-del-object-delete-it%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
5
del
only unbinds the variable name, it does not guarantee that the object gets destroyed immediately, as stated in the docs: docs.python.org/3/reference/datamodel.html#object.__del__– UnholySheep
Nov 11 at 18:17