Class data attribute not being accessible in class method - python

I have written a small program that will print all the files and directories inside the path specified by me. The source code is:
import os
import glob
class FolderStats:
targetdir = ""
def __init__(self, dirpath = None):
targetdir = dirpath
totalfiles = 0
totalsubfolders = 0
def FolderIterator(self):
print self.targetdir
listing = os.listdir(self.targetdir)
for infile in listing:
print "current file is: %s" % (infile)
if __name__ == '__main__':
Obj = FolderStats(raw_input('Enter your path: '))
Obj.FolderIterator()
The above code is not executing. I am getting an error in the method FolderIterator: when the print command is executed, it prints nothing. <targetdir> no more contains the path supplied by me. Why is it so?

In your __init__ you need to use self.targetdir instead of targetdir
>>> class Test:
var = 1
def __init__(self):
var = 2
print self.var # Object variable
print var # Local variable
def func(self):
print self.var
print var # this will fail, because there's no local var in this scope
>>> a = Test()
1
2
>>> a.func()
1
Traceback (most recent call last):
File "<pyshell#12>", line 1, in <module>
a.func()
File "<pyshell#10>", line 9, in func
print var
NameError: global name 'var' is not defined

Related

How to import class from different script, where the class uses a global variable at initialization?

From one file, I'm trying to import and initialize a class from another file, where that class is initialized with a global variable defined in the calling file.
My file setup looks like this.
folder
├──subfolder
│ └── __init__.py
│ └── sub.py
├──__init__.py
├──orig.py
My orig.py file looks like this:
from folder.subfolder.sub import Test
def varinit():
global var
var = 8
def runn():
varinit()
testInstance = Test()
testInstance.print_modvar()
if __name__ == "__main__":
runn()
My sub.py file looks like this:
from folder.orig import var
class Test():
def __init__(self):
self.mod_var=var+8
def print_modvar(self):
print(self.mod_var)
In my terminal, I set:
export PYTHONPATH=/path/to/rootfolder
Where rootfolder contains folder.
When I run python3 folder.orig.py I get this error:
Traceback (most recent call last):
File "folder/orig.py", line 1, in <module>
from folder.subfolder.sub import Test
File "/content/folder/subfolder/sub.py", line 1, in <module>
from folder.orig import var
File "/content/folder/orig.py", line 1, in <module>
from folder.subfolder.sub import Test
ImportError: cannot import name 'Test'
The issue is that it is not able to locate sub.py? Or is it able to locate sub.py, but just not the class defined in sub.py?
How can I modify this to be able to correctly import the class, with it correctly using the global variable at initialization?
The result is that it should print the number 16.
For convenience I have a colab notebook with the code that is interactive. The files likely won't persist though
https://colab.research.google.com/drive/1mYk-XTpQh5d8IoTzXg9phGc2WupYKlRU?usp=sharing
uh you make some mistakes
the global variable declaration is not like this, the global modifier is used to declarate a variable is the variable in the global rather than declarate a new one(Disambiguation), instead of declarate a global variable
and i thinks that you cannot import one file that import back, it will into a cycle
so there a two solution(PS:I use a.py is orig.py and b.py is sub.py)
use the var as a parameter into the Test, like this
from subfolder.b import Test
var = 0
def varinit():
global var
var = 8
def runn():
varinit()
testInstance = Test(var)
testInstance.print_modvar()
if __name__ == "__main__":
runn()
class Test:
def __init__(self, var):
self.mod_var = var + 8
def print_modvar(self):
print(self.mod_var)
use a config class to store the global variable
from subfolder.b import Test
from config import config
def varinit():
config.var = 8
def runn():
varinit()
testInstance = Test()
testInstance.print_modvar()
if __name__ == "__main__":
runn()
from config import config
class Test:
def __init__(self):
self.mod_var = config.var + 8
def print_modvar(self):
print(self.mod_var)
config.py
class config:
var = 0
Var is not reachable from sub.py. You are trying to import sub from orig, and orig from sub. That doesn't really work.
Instead you can move varinit to the sub file and use it from there.
orig.py:
from subfolder.sub import Test
def runn():
testInstance = Test()
testInstance.print_modvar()
if __name__ == "__main__":
runn()
sub.py:
global var
var = 8
class Test():
def __init__(self):
self.mod_var = var + 8
def print_modvar(self):
print(self.mod_var)
output:
16

Changing global variables and read them

I have properties file props.properties
[collect_data]
collect = True
And 2 files test2.py
import test1 as c
class Test:
def __init__(self):
pass
def printer(self):
print 'in test2 value is' c.COLLECT_DATA
And test1.py file with main function
from ConfigParser import ConfigParser
import test2 as t
DEFAULT_PROPS = '..//etc//props.properties'
COLLECT_DATA = False
class Initializer:
def __init__(self):
pass
def init_const(self, properties=DEFAULT_PROPS):
cfg = ConfigParser()
print 'Start'
cfg.read(properties)
global COLLECT_DATA = False
COLLECT_DATA = eval(cfg.get('collect_data', 'collect'))
print 'Now it is', COLLECT_DATA
if __name__ == '__main__':
i = Initializer()
i.init_const()
test = t.Test()
test.printer()
print COLLECT_DATA
I want to read properties from props file, assing it and read them in another file, but actually I have such logs:
Start
Now it True
in test2 value is False
True
How to solve it?

Python : how to use another method's returning value in another method?

what i am trying to do is get a returning value from abcd method, and use this value to as a the substitue of fname and the error is continues to occur.
how can i fix this error?
ICB164000395.txt has four lines.
and i want line_count print out 4(The number of lines in the text file)
class Test():
def abcd(self):
self.a = a
a = 'ICB164000395.txt'
return a
def line_count(self, fname):
with open(fname) as f:
for i, l in enumerate(f):
pass
return i + 1
print(i + 1)
t = Test()
t.line_count(abcd())
and the error appears like this
Traceback (most recent call last):
File "C:\Users\mg\Desktop\Tubuc\openAPI\test9.py", line 16, in
t.line_count(abcd(fname))
NameError: name 'abcd' is not defined
Just looking at the function:
def abcd(self):
self.a = a
a = 'ICB164000395.txt'
return a
I'm guessign you're getting an error at self.a = a .. Because a is not defined yet. It's not passed in either.
I think what you want is:
class Test():
def abcd(self):
a = 'ICB164000395.txt' # you'll need to correct the path to this file
return a
def line_count(self, fname):
with open(fname) as f:
for i, l in enumerate(f):
pass
return i + 1
print(i + 1)
t = Test()
t.line_count(t.abcd())
abcd is an instance method so you have to call it from an instance of your class
t = Test()
t.line_cont(t.abcd())
Your abcd method also uses the variable a before it is ever defined, so you could change it to
def abcd(self):
self.a = 'ICB164000395.txt'
return self.a
It appears what you want from your abcd method is typically handled in an init. You can set the file name when you instantiate a Test object. Then you can call the line count. Your line_count method should also specify how you are opening the file 'r' for read mode.
class Test():
def __init__(self, file_name):
self._file_name = file_name
def line_count(self):
with open(self._file_name, 'r') as f:
for i, l in enumerate(f):
pass
return i + 1
print(i + 1)
t = Test('ICB164000395.txt')
t.line_count()

Python: How to access instance member from other module?

I'm a beginner struggling with calling an instance member from another module. My code is quite long, but I can reproduce the issue with this snippet:
mainmodule.py:
from othermodule import *
class Class2_in_main():
mystring = 'Initial Value'
print mystring
def change_string(self, NewStringValue):
self.mystring = NewStringValue
print self.mystring
def main():
MyObjectInstance = Class2_in_main()
Object2 = othermodule.Class_in_othermodule()
if __name__ == '__main__':
main()
othermodule.py:
from mainmodule import *
class Class_in_othermodule():
MyObjectInstance().change_string('New String Value!')
Here's my stack:
Initial Value
Traceback (most recent call last):
File "mainmodule.py", line 1, in <module>
from othermodule import *
File "C:\PythonScripts\StackOverflowExample\othermodule.py", line 3, in <module>
class Class_in_othermodule():
File "C:\PythonScripts\StackOverflowExample\othermodule.py", line 6, in Class_in_othermodule
MyObjectInstance().change_string('New String Value!')
NameError: name 'MyObjectInstance' is not defined
I use Python 2.7.
Any idea? I'm sorry for the bad formatting, it's my first question here, and I can't figure out how that works!
Update: I was able to have my code working, but I would like to understand how to call "change_string" specifically for my instance only (called MyObjectInstance), how could I do that?? Here is what I currently have:
mainmodule.py:
import othermodule
class Class2_in_main():
mystring = 'Initial Value'
print mystring
def change_string(self, NewStringValue):
self.mystring = NewStringValue
print self.mystring
def main():
global MyObjectInstance
MyObjectInstance = Class2_in_main()
Object2 = othermodule.Class_in_othermodule()
if __name__ == '__main__':
main()
othermodule.py:
class Class_in_othermodule():
mainmodule.Class2_in_main().change_string('New String Value!')

Global variable error, despite declaring variable as global in each function

I'm trying to use a global variable. I've declared it as global to begin with and the declare it at such at each mention, but I get a NameError after the first function completes. Here's the code, and I think I've gone stare crazy but I can't seem to find the problem.
def on_servername_insertatcursor(self, widget):
global output
output = StringIO.StringIO()
servername = widget.get_text()
output.write("USHARE_NAME="+servername+'\n')
def on_netif_changed(self, widget):
netif = widget.get_active_text()
global output
output.write("USHARE_IFACE="+netif+'\n')
def on_port_insertatcursor(self, widget):
global output
port = widget.get_text()
output.write("USHARE_PORT="+port+'\n')
def on_telprt_insertatcursor(self, widget):
global output
telprt = widget.get_text()
output.write("USHARE_TELNET_PORT="+telprt+'\n')
def on_dirs_insertatcursor(self, widget):
global output
dirs = widget.get_text()
output.write("USHARE_DIR="+dirs+'\n')
def on_iconv_toggled(self, widget):
global output
iconv = widget.get_active()
if iconv == True:
output.write("USHARE_OVERRIDE_ICONV_ERR="+"True"+'\n')
else:
output.write("USHARE_OVERRIDE_ICONV_ERR="+"False"+'\n')
def on_webif_toggled(self, widget):
global output
webif = widget.get_active()
if webif == True:
output.write("USHARE_ENABLE_WEB="+"yes"+'\n')
else:
output.write("USHARE_ENABLE_WEB="+"no"+'\n')
def on_telif_toggled(self, widget):
global output
telif = widget.get_active()
if telif == True:
output.write("USHARE_ENABLE_TELNET="+"yes"+'\n')
else:
output.write("USHARE_ENABLE_TELNET="+"no"+'\n')
def on_xbox_toggled(self, widget):
global output
xbox = widget.get_active()
if xbox == True:
output.write("USHARE_ENABLE_XBOX="+"yes"+'\n')
else:
output.write("USHARE_ENABLE_XBOX="+"no"+'\n')
def on_dlna_toggled(self, widget):
global output
dlna = widget.get_active()
if dlna == True:
output.write("USHARE_ENABLE_DLNA="+"yes"+'\n')
else:
output.write("USHARE_ENABLE_DLNA="+"no"+'\n')
def on_commit_clicked(self, widget):
commit = output.getvalue()
logfile = open('/home/boywithaxe/Desktop/ushare.conf','w')
logfile.write(commit)
def on_endprogram_clicked(self, widget):
sys.exit(0)
What's amazing is that when insertatcursor (coming from Gtk.TextBuffer.insert_at_cursor() ) is replace with activate, the code works perfectly, except I don't want to have the user have to press enter after every data input.
EDIT. The Traceback is as follows
Traceback (most recent call last):
File "/home/boywithaxe/Developer/Quickly/broadcast/broadcast/BroadcastWindow.py", line 58, in on_netif_changed
output.write("USHARE_IFACE="+netif+'\n')
NameError: global name 'output' is not defined
Having made the changes suggested by #jdi (Thank you btw, I see the logic behind that), the Traceback I get is as follows:
Traceback (most recent call last):
File "/home/boywithaxe/Developer/Quickly/broadcast/broadcast/BroadcastWindow.py", line 55, in on_netif_changed
OUTPUT.write("USHARE_IFACE="+netif+'\n')
NameError: global name 'OUTPUT' is not defined
Traceback (most recent call last):
File "/home/boywithaxe/Developer/Quickly/broadcast/broadcast/BroadcastWindow.py", line 72, in on_iconv_toggled
OUTPUT.write("USHARE_OVERRIDE_ICONV_ERR="+"True"+'\n')
NameError: global name 'OUTPUT' is not defined
Traceback (most recent call last):
File "/home/boywithaxe/Developer/Quickly/broadcast/broadcast/BroadcastWindow.py", line 79, in on_webif_toggled
OUTPUT.write("USHARE_ENABLE_WEB="+"yes"+'\n')
NameError: global name 'OUTPUT' is not defined
Traceback (most recent call last):
File "/home/boywithaxe/Developer/Quickly/broadcast/broadcast/BroadcastWindow.py", line 86, in on_telif_toggled
OUTPUT.write("USHARE_ENABLE_TELNET="+"yes"+'\n')
NameError: global name 'OUTPUT' is not defined
Traceback (most recent call last):
File "/home/boywithaxe/Developer/Quickly/broadcast/broadcast/BroadcastWindow.py", line 93, in on_xbox_toggled
OUTPUT.write("USHARE_ENABLE_XBOX="+"yes"+'\n')
NameError: global name 'OUTPUT' is not defined
Traceback (most recent call last):
File "/home/boywithaxe/Developer/Quickly/broadcast/broadcast/BroadcastWindow.py", line 100, in on_dlna_toggled
OUTPUT.write("USHARE_ENABLE_DLNA="+"yes"+'\n')
NameError: global name 'OUTPUT' is not defined
Traceback (most recent call last):
File "/home/boywithaxe/Developer/Quickly/broadcast/broadcast/BroadcastWindow.py", line 105, in on_commit_clicked
commit = OUTPUT.getvalue()
NameError: global name 'OUTPUT' is not defined
Your code example doesn't require a global. Just remove it. The only time you need to use the global keyword in a function is if you are going to assign to it.
OUTPUT = StringIO.StringIO()
def on_servername_insertatcursor(self, widget):
servername = widget.get_text()
OUTPUT.write("USHARE_NAME="+servername+'\n')
def on_netif_changed(self, widget):
netif = widget.get_active_text()
OUTPUT.write("USHARE_IFACE="+netif+'\n')
def on_port_insertatcursor(self, widget):
port = widget.get_text()
OUTPUT.write("USHARE_PORT="+port+'\n')
def on_telprt_insertatcursor(self, widget):
telprt = widget.get_text()
OUTPUT.write("USHARE_TELNET_PORT="+telprt+'\n')
def on_dirs_insertatcursor(self, widget):
dirs = widget.get_text()
OUTPUT.write("USHARE_DIR="+dirs+'\n')
def on_iconv_toggled(self, widget):
iconv = widget.get_active()
if iconv == True:
OUTPUT.write("USHARE_OVERRIDE_ICONV_ERR="+"True"+'\n')
else:
OUTPUT.write("USHARE_OVERRIDE_ICONV_ERR="+"False"+'\n')
Even if you wanted to be able to reset your StringIO object in a function, it still wouldn't require an assignment or global keyword:
def reset_output(self):
OUTPUT.seek(0)
OUTPUT.truncate()
Proof that it works
import StringIO
OUTPUT = StringIO.StringIO()
def foo():
OUTPUT.write('foo')
def bar():
OUTPUT.write('bar')
def print_output():
print OUTPUT.getvalue()
def reset_output():
OUTPUT.seek(0)
OUTPUT.truncate()
if __name__ == "__main__":
foo()
bar()
print_output()
reset_output()
print_output()
Output
$ python test.py
foobar
$
Try moving output = StringIO.StringIO() outside and above all the functions in the file.
Well, the problem with the question is unfortunate indenting :) Looking at PyGTK docs shows that the on_... functions shown are indeed methods of a class, not global functions, so the "global" variable is probably not really global but also a member of the class (just look at the self parameter in method definitions).
I gave a more detailed answer on askubuntu, here's a code snippet which shows what needs to be done:
class MyApp(gtk.Window):
output = None
def __init__(...):
...
self.output = StringIO.StringIO()
def on_servername_insertatcursor(self, widget):
servername = widget.get_text()
self.output.write("USHARE_NAME="+servername+'\n')
def on_netif_changed(self, widget):
netif = widget.get_active_text()
self.output.write("USHARE_IFACE="+netif+'\n')
There's absolutely no PyGTK-specific or signals-specific magic involved :)

Categories

Resources