I have 2 .py files. Let's name them foo.py and list.py
list.py is not having any code but just a list which looks like this: allowed = ['a', 'b', 'c']
This is all the list.py contains...
Now, the foo.py has a code which basically uses the list inside the list.py to only allow certain inputs (which should be in the list, else: pass)
I added a code to be able to add elements to the list from inside the program, but i'm unable to do so. I have tried to use the append() function. This brings no change to the list...
Please help me edit and write changes to the list inside list.py by providing the right code to so.
Thanks.
What is likely happening is you are sending a copy of the list, when your program is running - and then appending to that list - without impacting the initial list in list.py
I would look at making sure that when you instantiate the original list in list.py, you aren't doing so in such a way that means each time that code block is called, the list is defined again as you call that code block or function again.
If you are trying to use a program in foo.py to explicitly edit the list.py file, you are probably as well off to simply use python's pickle module, which saves the state of python objects to file, and you would then be able to load them as normal later, for example:
try:
with open(list, 'r') as file:
yourlist = pickle.load(file)
except(FileNotFoundError):
yourlist = ['someDefaultValue','anotherDefaultValue']
# Your code block, doing whatever you're doing
with open(list, 'w') as file:
pickle.dump(yourlist, file)
Without knowing more about what you're looking at or exactly what you're trying to do - it's hard to give a better answer!
Related
Im trying to make a thing that can detect whether or not a user wants their password stored for next time they run the program, The reason im using a boolean for this is so in the files that need to use the password they can check to see if storepass is True then get the pass/user from a .env if not they can get the password from the storepasswordquestion file amd use that and it wont get stored when the user closes the program.
I have a file called booleans that im using to store booleans, in it is this:
storepass = False
In a other file called storepasswordquestion i have:
import booleans
username = 'username'
password = 'password'
question = input('Would you like your password to be stored for use next time?') # enter y
if question == 'y':
booleans.storepass = True
# store password/username in .env
As i understand it import booleans loads the booleans file, Then i think booleans.storepass is like a variable but like a copy of the one in booleans? Because when i go on the booleans file again its still False.
Im needing to change storepass to True in the booleans file and then save it.
Then i think booleans.storepass is like a variable but like a copy of the one in booleans? Because when i go on the booleans file again its still False.
That's correct - you can't change the values inside a .py file just by importing and then setting within another. py file. The standard way to manipulate files is by using some variation of
with open('boolean.py', 'w') as f:
f.write('storepass = False')
Personally, I really dislike writing over .py files like this; I usually save as JSON. So "boolean.json" can have just
{"storepass": false}
and then in your python code you can (instead of importing) get it as
# import json
boolean = json.load(open('boolean.json', 'r'))
and set storepass with
# import json
boolean.storepass = True
with open('boolean.json', 'w') as f:
json.dump(boolean, f, indent=4)
## NOT f.write(boolean)
and this way, if there are more values in boolean, they'll also be preserved (as long as you don't use the variable for anything else in between...)
You're expecting changing a variable's value to change source code. Luckily, that's not how this works!
You need to make a mental distinction between the source code that the python interpreter reads, and the values of variables.
What you need is indeed, as you say,
Im needing to change storepass to True in the booleans file and then save it.
So, you would need to open that boooleans.py as a text file, not as a python program, read and interpret it as pairs of keys and values, modify the right one (so, storepass in this case), write the result back to the file. Then, the next time someone imports it, they would see the different setting.
This is a bad approach you've chosen:
Reading and parsing python files is very hard in general, because, well, Python is a programming language and can do much more than just store settings
The change only takes effect the next time the program is run and the settings are imported anew. This has no effect on other parts of an already running program. So, that's bad.
Things get a lot easier if you do two things:
Get rid of the idea to store settings in a Python source code file. Instead, use one of the multiple ways that python has to read structured data from a file. For your use case, usage of the configparser module might be easiest – a ConfigParser has a read and a write method, with which you can, you guessed it, read and write your config file. There's multiple other modules that Python brings that can do similar things. The json module, for example, is a sensible way to store especially logically hierarchically structured settings. And of course, the place where you store passwords might also be a place where you could store settings – depending on what that is.
The approach of having a single module that you import (your booleans) is a good one, as it ensures that there's a single booleans that is the "source of truth" about these settings. I propose you put the configuration loading into such a single module:
# this is settings.py
import json
SETTINGSFILE = "settings.json"
# when this is loaded the first time, load things from the settings file
try:
with open(SETTINGSFILE) as sfile:
_settings = json.load(sfile)
except FileNotFoundError:
# no settings file yet. We'll just have empty settings
# Saving these will create a file
_settings = {}
def __getattr__(settingname):
try:
return _settings[settingname]
except KeyError as e:
# you could implement "default settings" by checking
# in a default settings dictionary that you create above
# but here, we simply say: nay, that setting doesn't yet
# exist. Which is as good as your code would have done!
raise AttributeError(*e.args) from e
def save():
with open(SETTINGSFILE, "w") as sfile:
json.dump(_settings, sfile)
def update_setting(settingname, value):
_settings[settingname] = value
save()
which you can then use like this:
import settings
…
if settings.storepass:
"Do what you want here"
…
# User said they want to change the setting:
should_we_store = (input("should we store the password? ").upper == "Y")
# this updates the setting, i.e. it's instantly visible
# in other parts of the program, and also stores the changed config
# to the settings.json file
settings.update_setting("storepass", should_we_store)
You are changing the value inside the runtime, meaning you can actually change it. Meaning if you are ever trying to print out the value inside the if condition like this:
booleans.storepass = True
print(booleans.storepass)#This should return True
But your problem is that you are not actually changing the file. In order to change the file you should do it like this( This is the general way to write to a file with python from my research it should work in your case as well.
f = open("booleans.py", "w")
f.write("booleans.storepass = True")
f.close()
In short what you are doing is actually true for runtime, but if you want to store the result in a file this is the way to do it.
I have a project named project1, where I take a big .txt file (around 1 GB). I make a list that has each line of the text as elements, with the following code:
txt = open('<path>', 'r', encoding="utf8")
lista = list(txt)
And then I edit the items in the list, which is not important for my question.
I need to use the variable lista in another project (project2), but i don't want to import it in the following way
from project1 import lista
because by doing that I have to run all the code in project1 to get the text in the .txt file and to edit the list.
So my goal is to use lista without having to run code that takes time, since lista will always be the same.
IMPORTANT NOTES
I can't just print it in project1, copy the output and paste it in project2 to use it as a variable, because the list is way too long.
One way I thought about that was to save lista as a string in a .txt file (let's call it lista.txt), open the .txt file in project2 and, in some way, tell python that the string in lista.txt is actually a list. Example to understand better:
In project 1
file_text = open('<path>\\lista.txt', 'w', encoding="utf8")
lista = ['<string_1>', '<string_2>', ..., '<string_n>']
file_text.write(f'{lista}')
file_text.close()
In project 2
file_text = open('<path>\\lista.txt', 'r', encoding="utf8")
list_as_string = file_text
def string_to_list(input_string):
#way to transform the list_as_string into the original "lista" variable, which is a list
#return list
string_to_list(list_as_string)
IMPORTANT: The way that I described looks to complex to me, so it was just an idea, but I'm sure there are better ways (maybe there is a way to save a python variable as a file that keeps information like its type and the directly import it in a project as a variable of that type, in this case a list)
May I suggest that you use txt.readlines() instead of list(txt) in order to get the lines unless every line in the file contains a single character. In Json/Pickle; dump/dumps enable you to save an object to an open file (you could save the list to a file) or obtain the source/bytes, respectively, that would be saved in a writable-file-object; load/loads allows to restore the content from the corresponding dump. Personally I would just make a new list using the file's path or encapsulate the code in the other script to make it less slow on import.
Does anyone know of a way to name a list in python using a String. I am writing a script that iterates through a directory and parses each file and and generates lists with the contents of the file. I would like to use the filename to name each array. I was wondering if there was a way to do it similar to the exec() method but using lists instead of just a normal variable
If you really want to do it this way, then for instance:
import os
directory = os.getcwd() # current directory or any other you would like to specify
for name in os.listdir(directory):
globals()[name] = []
Each of the lists can be now referenced with the name of the file. Of course, this is a suboptimal approach, normally you should use other data structures, such as dictionaries, to perform your task.
You would be better off using a dictionary. Store the file name as the key value of the dictionary and place the contents inside the corresponding value for the key.
It's like
my_dict = {'file1.txt':'This is the contents of file1','file2.txt':'This is the content of file2'}
i was wondering if this is a common Problem:
I myself wrote a Program which copys files (if found) from one place to another. The first call is os.path.isfile(wholepath+file)
But this call never return something. Instead the Program stops. The Problem could be that there are 1 millions of files (multiple TB). In this case, is there another better solution?
The Program is now running for an hour and does not need much cpu (htop)
isfile() returns True if path is an existing regular file.
try this one:
print [fle for fle in os.listdir(wholepath) if os.path.isfile(os.path.join(wholepath, fle))]
Note that your list will return as an empty list if your path consists of only folders and not files.
I'm using the following code to iterate through an xml file, I want to extract the folder structure.
Ideally I'd like a list in which each element would have the following structure:
top_folder, first_folder, page_view
Alternatively a dictionary with top_folder and page_view would also work for me.
The problem I'm having is that if I try to print the variable from the previous for loop, it doesn't work. Which I don't understand, as I'm use it in other parts of the script.
The code is:
top = ""
for first_iter in root_navigation:
for second_iter in first_iter:
for top_folder in second_iter:
if top_folder.text and top_folder.text.strip():
#print top_folder.text
top == top_folder.text
for first_folder in top_folder:
if first_folder.text and first_folder.text.strip():
#print " "+first_folder.text
first = first_folder.text
for page_view in first_folder:
if page_view.text and page_view.text.strip():
#print " "+page_view.text
print top+":"+first+":"+page_view.text
So far I've tried the above code, and directly printing the top_folder.text and first_folder.text in the last if.
The only output I manage to get, the commented prints is something like:
Top Folder
First Folder
Page View
First Folder
Page View
.....
Which doesn't really work as I'd like to have a list or something I could match later with the view name and get the top folder for it.
Any ideas of why the variables are not getting across the for loops or another way I could do this?
Thanks in advance :-)