I'm trying to access variables I created in one function inside another module in Python to plot a graph however, Python can't find them.
Heres some example code:
class1:
def method1
var1 = []
var2 = []
#Do something with var1 and var2
print var1
print var2
return var1,var2
sample = class1()
sample.method1
here is class 2
from class1 import *
class number2:
sample.method1()
This does as intended and prints var1 and var2 but I can't call var1 or var2 inside class number 2
FIXED EDIT:
Incase anyone else has this issue, I fixed it by importing this above class two
from Module1 import Class1,sample
And then inside class2
var1,var2 = smaple.method1()
The code you posted is full of syntax errors as Francesco sayed in his comment. Perhaps you could paste the correct one.
You don't import from a class but from a package or a module. Plus you don't "call" a variable unless it's a callable.
In your case you could just have :
file1.py :
class class1:
def __init__(self): # In your class's code, self is the current instance (= this for othe languages, it's always the first parameter.)
self.var = 0
def method1(self):
print(self.var)
sample = class1()
file2.py :
from file1 import class1, sample
class class2(class1):
def method2(self):
self.var += 1
print(self.var)
v = class2() # create an instance of class2 that inherits from class1
v.method1() # calls method inherited from class1 that prints the var instance variable
sample.method1() # same
print(v.var) # You can also access it from outside the class definition.
v.var += 2 # You also can modify it.
print(v.var)
v.method2() # Increment the variable, then print it.
v.method2() # same.
sample.method1() # Print var from sample.
#sample.method2() <--- not possible because sample is an instance of class1 and not of class2
Note that to have method1() in class2, class2 must inherit from class1. But you can still import variables from other packages/modules.
Note also that var is unique for each instance of the class.
Related
I'm new with Python and I'm trying to use classes to program using objects as I do with C++.
I wrote 3 .py files.
a.py
from b import *
class A:
def __init__(self):
self.m_tName = "A"
def test(self):
tB = B()
tB.do( self )
b.py
from a import *
class B:
def __init__(self):
self.m_tName = "B"
def do(self, tA ):
if not isinstance( tA, A ):
print ( "invalid parameter" )
print( "OK" )
demo.py:
from a import *
if __name__ == "__main__":
tA = A()
tA.test()
As you can see I want to use a A() object to call the member function test() that creates a B() object and call the member function do() that uses a A() object.
So in B::do() I want to check the parameters using the built-in function isinstance(). But python tells me that there's a NameError: global name 'A' is not defined.
The A() class file is imported at the top of the b.py file.
Does anyone know what I'm doing wrong here ?
As pointed in some comment, circular dependencies are not well handled if imported in the form from a import A.
In short, the problem with ... import * is that is causes the local scope to have all its declarations overridden, in effect making the identification of from which module (in your case) a class comes from. This causes exactly what you are facing.
Changing the import statement in the following way, together with a classified reference to a.A, produces OK as output.
import a
class B:
def __init__(self):
self.m_tName = "B"
def do(self, tA ):
print tA
if not isinstance( tA, a.A ):
print ( "invalid parameter" )
print( "OK" )
As a bit of additional information, this has already been discussed in Why is "import *" bad?. I would point in special to this answer: https://stackoverflow.com/a/2454460/1540197.
**Edit:**This article explain the import confusion.
You have a circular dependancy, a.py and b.py import each other.
You could move either import statement inside the method where it is used.
So b.py would become:
class A:
def __init__(self):
self.m_tName = "A"
def test(self):
from b import B
tB = B()
tB.do( self )
I have two files like the following
file1.py
class A:
def method1:
a = 5
file2.py
class B
def method2:
from file1 import A
a = 10
Forget the logic, its just an example. I wish to manipulate the value of a in my code. When I do this it gives me an error saying
"global name a is not defined". How can I solve this problem. Any help will be appreciated
The way you defined a it is a local variable to that method. What you want is self.a...
file1.py
class A:
def method1:
self.a = 5
file2.py
from file1 import A
class B:
def method2:
objecta = A()
objecta.a = 10
But reading your comments, what you actually want is something different.
Class A:
def __init__(self):
self.a = 5
def logic(self):
do some stuff...
Class B:
def solve(self):
first = A()
first.logic()
second = A()
second.logic()
etc...
The point of doing it with classes is that you can make multiple instances of the class. The init function creates an object of that class based on your baseline- so each time you make an A object, it will start out with your original settings.
I am looking for a way to access a subclasses variables from the parent class which is instantiated in a different file. For example
basefile.py:
class A(object): #gets subclassed
var = 0 #place holder
def printTheVar(self):
print self.var
class B(object):
def buildAndCallA(self):
a = A()
a.printTheVar()
implementationfile.py:
from basefile import *
class A(A):
var = 10
if __name__ == '__main__':
b = B()
b.buildAndCallA()
When I run:
$ python implementationfile.py
I get 0. I want to get 10
When both parent class and implementation class are in the same file, this is obviously not a problem but I have a project structure which requires they not be:
somedir/
| basefile.py
| implementations/
| -- implementationA.py
| -- implementationB.py
| -- implementationC.py
I think that the abc module might help but my experiments with that have proven fruitless so far.
I'd suggest, if possible, you pass the class you want to use to the buildAndCallA method. So it should look something like this:
def buildAndCallA(self,cls):
a = cls()
a.printTheVar()
And then you can call it like this:
b.buildAndCallA(A)
Then it will use whatever version of the A class is in scope at the time it is called.
You could even set it up with a default parameter, so it will use the version of A in the base file by default, but you can still override it when necessary.
def buildAndCallA(self,cls=A):
a = cls()
a.printTheVar()
Then if you call b.buildAndCallA() with no parameter, it will construct an instance of the A class from the base file.
#James's answer got me most of the ways there. Here is a more global way to do it using three files for clarity (which is really how the project is organized anyways)
script.py:
if __name__ == '__main__':
if sys.argv[0] == 'useImplementation1'
import implementations.implementation1 as implementation
elif sys.argv[1] == 'useImplementation2':
import implementations.implementation2 as implementation
b = implementation.B(cls=implementation)
b.buildAndCallA()
basefile.py (notice the A = cls.A this is the key):
class A(object):
var = 0 #place holder
def printTheVar(self):
print self.var
class B(object):
def __init__(self,cls):
global A
A = cls.A
def buildAndCallA(self):
a = A()
a.printTheVar()
implementation1.py:
from basefile import *
class A(A):
var = 10
What is the difference between creating a variable using the self.variable syntax and creating one without?
I was testing it out and I can still access both from an instance:
class TestClass(object):
j = 10
def __init__(self):
self.i = 20
if __name__ == '__main__':
testInstance = TestClass()
print testInstance.i
print testInstance.j
However, if I swap the location of the self, it results in an error.
class TestClass(object):
self.j = 10
def __init__(self):
i = 20
if __name__ == '__main__':
testInstance = TestClass()
print testInstance.i
print testInstance.j
>>NameError: name 'self' is not defined
So I gather that self has a special role in initialization.. but, I just don't quite get what it is.
self refers to the current instance of the class. If you declare a variable outside of a function body, you're referring to the class itself, not an instance, and thus all instances of the class will share the same value for that attribute.
In addition, variables declared as part of the class (rather than part of an instance) can be accessed as part of the class itself:
class Foo(object):
a = 1
one = Foo()
two = Foo()
Foo.a = 3
Since this value is class-wide, not only can you read it directly from the class:
print Foo.a # prints 3
But it will also change the value for every instance of the class:
print one.a # prints 3
print two.a # prints 3
Note, however, that this is only the case if you don't override a class variable with an instance variable. For instance, if you created the following:
class Bar(object)
a = 1
def __init__(self):
self.a = 2
and then did the following:
one = Bar()
two = Bar()
two.a = 3
Then you'd get the following results:
print Bar.a # prints "1"
print one.a # prints "2"
print two.a # prints "3"
As noted in the comments, assigning to two.a creates an instance-local entry on that instance, which overrides the a from Bar, hence why Bar.a is still 1 but two.a is 3.
j is a class variable as pointed by Amber. Now, if you come from C++ background, self is akin to the this pointer. While python doesn't deal with pointers, self plays the similar role of referring to current instance of the class.
In the python way, explicit is better than implicit. In C++, the availability of this is conventionally assumed for each class. Python, on the other hand, explicitly passes self as first argument to each of your instance methods.
Hence self is available only inside the scope of your instance methods, making it undefined for the place from which you tried using it.
Since you're made to explicitly pass self to instance methods, you could also call it something else if you want to -
>>> class Foo:
... b = 20
... def __init__(them):
... them.beep = "weee"
...
>>> f = Foo()
>>> f.beep
'weee'
class foo():
def __init__(self)
self.var1 = 1
class bar():
def __init__(self):
print "foo var1"
f = foo()
b = bar()
In foo, I am doing something that produces "var1" being set to 1
In bar, I would like to access the contents of var1
How can I access var1 in the class instance f of foo from within the instance b of bar
Basically these classes are different wxframes. So for example in one window the user may be putting in input data, in the second window, it uses that input data to produce an output. In C++, I would have a pointer to the caller but I dont know how to access the caller in python.
As a general way for different pages in wxPython to access and edit the same information consider creating an instance of info class in your MainFrame (or whatever you've called it) class and then passing that instance onto any other pages it creates. For example:
class info():
def __init__(self):
self.info1 = 1
self.info2 = 'time'
print 'initialised'
class MainFrame():
def __init__(self):
a=info()
print a.info1
b=page1(a)
c=page2(a)
print a.info1
class page1():
def __init__(self, information):
self.info=information
self.info.info1=3
class page2():
def __init__(self, information):
self.info=information
print self.info.info1
t=MainFrame()
Output is:
initialised
1
3
3
info is only initialised once proving there is only one instance but page1 has changed the info1 varible to 3 and page2 has registered that change.
No one has provided a code example showing a way to do this without changing the init arguments. You could simply use a variable in the outer scope that defines the two classes. This won't work if one class is defined in a separate source file from the other however.
var1 = None
class foo():
def __init__(self)
self.var1 = var1 = 1
class bar():
def __init__(self):
print var1
f = foo()
b = bar()
Same as in any language.
class Foo(object):
def __init__(self):
self.x = 42
class Bar(object):
def __init__(self, foo):
print foo.x
a = Foo()
b = Bar(a)
Alternatively you could have a common base class from which both derived classes inherit the class variable var1. This way all instances of derived classes can have access to the variable.
Something like:
class foo():
def __init__(self)
self.var1 = 1
class bar():
def __init__(self, foo):
print foo.var1
f = foo()
b = bar(foo)
You should be able to pass around objects in Python just like you pass around pointers in c++.
Perhaps this was added to the language since this question was asked...
The global keyword will help.
x = 5
class Foo():
def foo_func(self):
global x # try commenting this out. that would mean foo_func()
# is creating its own x variable and assigning it a
# value of 3 instead of changing the value of global x
x = 3
class Bar():
def bar_func(self):
print(x)
def run():
bar = Bar() # create instance of Bar and call its
bar.bar_func() # function that will print the current value of x
foo = Foo() # init Foo class and call its function
foo.foo_func() # which will add 3 to the global x variable
bar.bar_func() # call Bar's function again confirming the global
# x variable was changed
if __name__ == '__main__':
run()