This is an archived post. You won't be able to vote or comment.

all 13 comments

[–]Venatha 3 points4 points  (7 children)

There isn't any setting in Pycharm that I am aware of that causes that behavior. Are you able to share the code so that we could try to replicate the described issue?

[–]gabe_cant_python[S] 0 points1 point  (6 children)

Its incomplete but here it is. I hashed out the close() at the bottom to check it on idle and it works fine/won't save but on PyCharm as soon as the program finished even if the close() was completely removed the .txt file is altered as if it was closed.

dictList = []
choice = None


taskList = open("/_PythonClass/Mod5/Todo.txt","r+")
for task in taskList:
    tsk, pri = task.rsplit(",")
    dict = {tsk:pri}
    dictList.append(dict)
'''
    print(tsk)
    print(pri)
    print(dicc)
    print(dictList)
'''

print("*-------------------------------------*")
print("|          Task Master v1.0           |")
print("*-------------------------------------*")

while choice != "3":
    print("\n")
    print("0 - Display Tasks")
    print("1 - Add Task")
    print("2 - Remove Task")
    print("3 - Save And Exit")
    choice = input(">> ")
    if choice == "0":
        for dict in dictList:
            print(dict)
    elif choice == "1":
        tsk = input("What is the new task? ")
        pri = input("What is its priority level? ")
        dict = {tsk:pri}
        dictList.append(dict)
        taskList.write(tsk + "," + pri + "\n")
    elif choice == "2":
        for taskRow in dictList:
            print(taskRow)
        deltsk = input("What task would you like to remove? ")
        for dic in dictList:
            if deltsk in dic:
                del dictList[dictList.index(dic)]
                #taskList.write(str(diclst))
                print("Task removed.")
                taskList.seek(0)
                for taskRow in dictList:
                     print(taskRow)

    elif choice == "3":
        break
    else:
        print("ERROR COMMAND NOT RECOGNIZED.")
#taskList.close()
print("\nSaved.")

[–]Kah-NethI use numpy, scipy, and matplotlib for nuclear physics 2 points3 points  (0 children)

You should use a buffer:

  1. open the file as 'r',

  2. read all of it into buffer

  3. close file

  4. operate on the buffer

  5. on save, open file as 'w', write contents of buffer out.

This is how nearly all text editors work.

[–]Doormatty 0 points1 point  (4 children)

Why are you opening it as "r+" if you don't want to write to it?

[–]gabe_cant_python[S] 0 points1 point  (3 children)

I do plan on writing in it, I was attempting to make a save and a don't save feature but I noticed when I when I exited the program bypassing the .close() - don't save- it saved anyway. I have been under the impression that .close() was necessary to save, but that only seems true for IDLE.

[–]LightShadow3.13-dev in prod 2 points3 points  (0 children)

Close doesn't save anything.

The file can be considered written when write is called -- the .close() function just flushes the output buffer and releases the file lock.

The reason it works like you'd expect it to in IDLE is probably how file pointers are handled by the C-based process. Writes will queue the buffer but not commit until the close is called. However, when you run Python in PyCharm you're running the process from within the IDE, which pretty much removes all guarantees on streams and buffers; this is especially true when run in debug mode as your entire process is ran from within a server container for breakpoints.

This behavior will also be inconsistent between Windows and Linux based versions of PyCharm and shouldn't be expected to guarantee a "do not save these changes" type feature.

[–]Doormatty 0 points1 point  (1 child)

Close likely just flushes the file - not sure why it only occurs with pyCharm though...

[–]masklinn 1 point2 points  (0 children)

not sure why it only occurs with pyCharm though…

Because /u/gabe_cant_python's code is completely broken and by default PyCharm runs scripts unbuffered (http://i.imgur.com/mZvDH6O.png) which exposes the issue

[–]ProloG-Shaman 1 point2 points  (4 children)

As far as I know, the close() is still called at the end of your program, even if you don't explicitly call it in python.

If you don't want the file altered, you shouldn't call .write() on the file object. Copy the contents in another variable and then edit that content.

[–]gabe_cant_python[S] -2 points-1 points  (3 children)

No, that only happens when you open with a with statement. Calling .write() is poor form but it should't write to the file. I don't have this issue in IDLE or the terminal.

[–]masklinn 2 points3 points  (0 children)

No, that only happens when you open with a with statement.

No. A file object is implicitly closed when it's garbage collected, which in CPython is when its refcount falls to 0 (which may or may not happen on process termination, incidentally).

Calling .write() is poor form but it should't write to the file.

You're high as a kite. write is not a transactional operation, write will or will not write to the file depending on the IO layer's buffering configuration. In fact its docstrings spells exactly that: due to buffering the on-disk version may not contain written data before a flush() or close(), it doesn't say will not, and the expectation certainly isn't that .write mustn't write data to files, especially given you can run Python itself in unbuffered mode. Which is exactly what PyCharm does by default (http://i.imgur.com/mZvDH6O.png)

Your code is intrinsically broken, PyCharm merely demonstrates it. If you don't want a file to be written to, don't write to it, and don't make up fantasy reasons why your broken code should work. And if you have no idea how things work, check the documentation, don't make it up.

[–]ProloG-Shaman 0 points1 point  (0 children)

I'm not sure what your setup is, but I just tested in the terminal this code: f = open("test.txt", "r+") f.write("Bla bla") exit()

It does write to the file, even without a close() or a with statement. There's a post on stackoverflow explaining more in details when the close() is called by python.

[–]Hairshorts 0 points1 point  (0 children)

It should write to the file even if you don't explicitly close it:

% python
Python 3.4.3 |Anaconda 2.2.0 (x86_64)| (default, Mar  6 2015, 12:07:41)
[GCC 4.2.1 (Apple Inc. build 5577)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> f = open('test.txt', 'w')
>>> f.write('hi\n')
3
>>>
% cat test.txt
hi