This is my code
class Mine:
def __init__(self):
var = "Hello"
def mfx(self):
var += "a method is called"
print var
me = Mine()
when i callme.mfx() it gives the following error
>>> me.mfx()
Traceback (most recent call last):
File "<pyshell#1>", line 1, in <module>
me.mfx()
File "D:\More\Pythonnnn\text.py", line 5, in mfx
var += "a method is called"
UnboundLocalError: local variable 'var' referenced before assignment
>>>
I need var only to use inside the class.
So i don't want self.var . Why is this happening?
How can I make a variable which can be used everywhere inside the class.
I am using Python2.7
You should qualify var. (self.var instead of var)
class Mine:
def __init__(self):
self.var = "Hello"
def mfx(self):
self.var += "a method is called"
print self.var
me = Mine()
me.mfx()
You must use self, otherwise you create a local variable that is only accessible inside the method it is created in.
you need to use self to access an instance variable. It's also better to use new style classes and also passed in parameter for your constructor
class Mine(object):
def __init__(self, var):
self.var = var
def mfx(self):
self.var += "a method is called"
print self.var
me = Mine()
me.mfx()
if you don't want to passed "hello" everytime, just create a default value
def __init__(self, var="hello"):
self.var = var
Related
I'm trying to break a tkinter app with several classes into multiple .py files. I'm using a Mixin class to import methods into each class. However, I'm struggling to access variables.
main.py contains a class creating the main window with a button to open a top level window and a button to get a variable from the Mixin.
# main.py
import tkinter
from tkinter import Tk
import customtkinter
import sys
sys.path.insert(1, "path/Classes")
from Classes import topLevel
# Main Window
class App(customtkinter.CTk):
def __init__(self):
super().__init__()
# Top Level Button
self.topLevel_button = customtkinter.CTkButton(master=self,
text="Open",
command=self.openTopLevel)
self.topLevel_button.grid(row=0, column=0)
# Get Variable
self.get_button = customtkinter.CTkButton(master=self,
text="Get Variable",
command=self.getVariable)
self.get_button.grid(row=1, column=0)
def openTopLevel(self):
window = topLevel.topLevel(self)
def getVariable(self):
print(var) # Can't access var
if __name__ == "__main__":
app = App()
app.mainloop()
topLevel.py is a class creating the top level window. It contains a variable fileSep to be used by a method in the Mixin Class:
# topLevel.py
sys.path.insert(1, "path/Methods")
from Methods import _topLevel
class topLevel(customtkinter.CTkToplevel, _topLevel.Mixin):
def __init__(self, parent):
super().__init__(parent)
# Create Variable
global fileSep
fileSep = customtkinter.StringVar(value="Comma")
print("Inside Class: " + fileSep.get()) # Works
# Create Button
self.loadButton = customtkinter.CTkButton(master=self,
text="Load",
command=self.loadFile)
self.loadButton.grid(row=0, column = 0, sticky='nswe')
# Attempt to access variable
def access_method(self):
print("Access Method: " + self.fileSep.get())
And _topLevel.py contains the mixin class:
# _topLevel.py
class Mixin:
def loadFile(self):
# Trying to access fileSep variable
print("Inside Mixin: " + fileSep.get()) # Error
topLevel().access_method() # Error
# I'm trying to access this variable from a function in main.py
var = "Hello World"
I get the following errors because the variables aren't accessible.
NameError: name 'var' is not defined
NameError: name 'fileSep' is not defined
I've tried making variables global as well as creating methods inside the class ( access_method() ) to print the variables as described here https://www.geeksforgeeks.org/python-using-variable-outside-and-inside-the-class-and-method/, but get the error:
TypeError: __init__() missing 1 required positional argument: 'parent'
How do I access variables that are defined in a class in the Mixin class? How would I access a variable created by the loadFile function in the Mixin Class for use in methods in the class App?
Thanks to #acw1668 comment, I just needed to make fileSep an instance variable:
self.fileSep = customtkinter.StringVar(value="Comma")
And to access it in the mixin class:
print("Inside Mixin: " + self.fileSep.get())
Equally I could create an instance variable to assign variable var to. For example in the topLevel class I added:
self.a = ""
And then assigned var to this variable within the function:
var = "Hello World"
self.a = var
Consider a class:
class Whatever:
rang = 'itselop'
def __init__ (self, name):
self.name = name
self.suka = name + " " + ' musorskaya'
#classmethod
def func(cls, attr):
cls.rang = attr
No error, if this passed in. I write then Whatever.func = 'patskak', expecting that this value shoud overwrite the class variable. But the class variable remains. I thought, this is because strings are immutable; but same thing repeats, when I make 2 integers as the class variable and the class method agrument. Why?
Thank you.
I am trying to add a setter method in an object:
object Foo {
def foo_=(s: String) = println(s)
}
Foo.foo = "test"
This does not work as expected, and compiler complains about "value foo is not a member of object Foo".
Why does it not work? How can I make it work, other than make a setter method without _=?
This seems to work just right in Scala 2.13
object Foo {
private var f: String = ""
def foo_=(s: String): Unit =
this.f = s.toLowerCase
def foo: String =
this.f
}
You can check like following.
Foo.foo
// res: String = ""
Foo.foo = "HELLO"
Foo.foo
// res: String = "hello"
Scala only recognizes this method as a setter if you have a getter def foo = ... as well:
If x is a parameterless method defined in some template, and the same template contains a setter method x_= as member, then the assignment x = e is interpreted as the invocation x_=(e) of that setter method.
From your comment:
Looks like 2.12.9 fixed it. It was broken with the version I was using 2.12.8.
Testing at https://scastie.scala-lang.org/8uAu5WCAQJa3darpMkCidg, I get the expected result: without a getter it fails in both 2.12.8 and 2.13.1, with one it works in both.
I want to have a var in a singleton object that I want to read from everywhere but only write into it from another singleton object (which is a companion object, but I don't think it matters here). Thus I put both objects into one file MyClass and made the var private but opened it up to the scope of the file with private[MyClass].
As a toy example: Everything is in the same file "MyClass.scala":
object OtherObject {
private[MyClass] var myvar = 0.0
def variable = myvar
}
object MyClass{
def setmyvar(myvar: Double): Unit = {
OtherObject.myvar = 2.0
}
}
class MyClass { ... }
This does not work however. I get the error "MyClass is not an enclosing class". How can I do what I want to do?
This will be not a companion object. You can have companion of class and object, both sharing the same name. Thus the error.
Putting that aside, you can achieve that what you asked for, by having both objects in the same package and limiting access with private to that package, or wrapping those objects with another one, and setting appropriate private modifier, like here:
object MyWrapper {
object OtherObject {
private[MyWrapper] var myvar = 0.0
def variable = myvar
}
object MyClass{
def setmyvar(myvar: Double): Unit = {
OtherObject.myvar = myvar
}
}
}
And then it works:
scala> MyWrapper.OtherObject.variable
res3: Double = 0.0
scala> MyWrapper.MyClass.setmyvar(3)
scala> MyWrapper.OtherObject.variable
res5: Double = 3.0
although it isn't especially elegant piece of code
but opened it up to the scope of the file
A file doesn't define a scope in Scala, period. So you can't make something writable only within the same file.
(There are actually three cases where files are relevant to scope that I can think of:
Top-level package statements have the rest of the entire file as their scope.
A class and an object with the same name are only companions if they are in the same file.
sealed traits or classes can only be extended in the same file.
None of them are useful for your question.)
A companion object must be defined inside the same source file as the class. Both should have same name. one should be class and another should be object type. Then only we can call it as companion.
object MyClass {
private[MyClass] var myvar = 0.0
def variable = myvar
}
class MyClass{
def setmyvar(myvar: Double): Unit = {
// your logic
}
}
http://daily-scala.blogspot.in/2009/09/companion-object.html
Is there an easy way to print the contents of what is returned from a new class object? I am testing with Fun Suite. Please see example below:
test("test") {
val contentString = new TestClass("test")
println("CONTENT IS: " + contentString)
}
The output is "CONTENT IS: TestClass#3c8bdd5b" and I would like to see "CONTENT IS: actual string content"
Thanks
You need to override the toString method. If you defined the class, you can do it inside the class definition as usual, e.g.:
class TestClass(val x: String){
override def toString = x
}
otherwise, you can extend the TestClass or create an anonymous class overriding the toString method, e.g.:
class TestClass(val x: String){
}
val z = new TestClass("hello world"){
override def toString = x
} // this will show " z: TestClass = hello world " in the REPL
You should override toString method of your TestClass.
Another possible solution use "case classes" that provides toString implementation.