i have following issue with the below python code:
templates.py
class globalSettings:
def __init__(self):
self.tx_wait = 1200
self.tx_Interval = 30
general.py
from templates import *
class testSuit(object):
def __init__(self):
testSuit.settings = globalSettings()
def readMeasurements(self, filename, revision, lsv):
testSuit.settings.tx_wait = 100
testSuit.settings.tx_Interval = 25
test.py
import general
from templates import *
class testcase(object):
def __init__(self):
self.settings = general.testSuit.settings
But this gives me:
self.settings = general_main.testSuit.settings
AttributeError: type object 'testSuit' has no attribute 'settings'
The several imports that i do are needed for the rest of the code!
What i want to achieve is to be able to load different settings for the globalSettings class but have default values.
So, the def readMeasurements is actually reading new values if found from an excel sheet. This part is working fine!
What am i doing wrong in my coding?
Thanks for your time!
Assuming you want the variables to be instance specific:
class testSuit(object):
def __init__(self):
testSuit.settings = globalSettings()
def readMeasurements(self, filename, revision, lsv):
testSuit.settings.tx_wait = 100
testSuit.settings.tx_Interval = 25
Should be:
class testSuit(object):
def __init__(self):
self.settings = globalSettings()
def readMeasurements(self, filename, revision, lsv):
self.settings.tx_wait = 100
self.settings.tx_Interval = 25
Assuming you want the variables to be static instead of instance defined, you should be able to use the following:
class testSuit(object):
settings = globalSettings()
def readMeasurements(self, filename, revision, lsv):
settings.tx_wait = 100
settings.tx_Interval = 25
You can declare settings = globalSettings() outside of the init function (which isn't needed here).
With your current code you may be able to access the variables by using:
self.settings = general.testSuit.testSuit.settings
Related
I have an external class to represent my data idk. Inside the class idk I want to have another class change which will contain various methods to change instances of the class idk. What I've tried is below. Note: this is a simplified example of my actual code
class idk:
def __init__(self):
self.x=1
self.y=2
class change:
def func(self):
self.x=10
self.y=100
var=idk()
var.change.func()
print(var.x, var.y)
However this gives the error:
TypeError: func() missing 1 required positional argument 'self'
How do I change the code to make it work?
Well, first of all, your are getting this error because you are accessing the func function as a class attribute and not by an instance of it (putting a class definition inside another class won't make it an instance).
If it makes sense, you cloud put those "change methods" in the idk class directly (that would be a normal approach):
class idk:
def __init__(self):
self.x = 1
self.y = 2
def func(self):
self.x = 10
self.y = 100
var = idk()
var.func()
print(var.x, var.y) # Output: 10 100
If you really want/need to separate those methods, you could do another class. The way I would implement that class is with static methods where all of them recieve an idk instance as the first parameter:
class idk:
def __init__(self):
self.x = 1
self.y = 2
class idkChanger:
#staticmethod
def func(idk_obj):
idk_obj.x = 10
idk_obj.y = 100
var = idk()
idkChanger.func(var)
print(var.x, var.y) # Output: 10 100
If you really really want/need to have that "changer" class inside of the idk class you can define it there, but this is not common at all. Also, you will have to pass the instance as well, that Changer class:
class idk:
def __init__(self):
self.x = 1
self.y = 2
class Changer:
#staticmethod
def func(idk_obj):
idk_obj.x = 10
idk_obj.y = 100
var = idk()
idk.Changer.func(var)
print(var.x, var.y) # Output: 10 100
Final notes:
You could not mark (decorate) the func as static and it will work the same, but this will bring more confution for several reasons (e.g., you would tecnically saying that func is an instance method. Which is not, because the objects you want to change are not Change's instances but idk's).
I have a question regarding the classes in python3. In my programm i have a "main" class that is getting started first and sets some parameters that are needed for the other parts of the programm. But now my other classes need some objects of the main class. How can i use the objects of the main class without initialising the main class everytime the subclass needs the object ? I looked into python inheritance but maybe i didnt understand it correctly
class Chunk(main.Main):
def __init__(self,pos_in_world_x,pos_in_world_y):
#self.chunksize = settings.blocks_per_chunk
self.prog = main.Main.prog
self.ctx = main.Main.ctx
this is my code for the subclass
You can use class variables:
class Main():
prog = 1
ctx = 2
def __init__(self):
pass
class Chunk(Main):
def __init__(self, pos_in_world_x, pos_in_world_y):
self.prog = Main.prog
self.ctx = Main.ctx
a = Chunk(3, 4)
print(a.prog) # 1
print(a.ctx) # 2
If you can't change Main to move your definitions outside __init__, then what you're asking for is impossible. If your variable is defined in __init__, you can't access it before calling __init__, i.e. initialising the class. You can't get round this.
You need a super __init__ call in your subclass and if you have that you only need to do:
class Chunk(main.Main):
def __init__(self,pos_in_world_x,pos_in_world_y):
super().__init__()
#self.chunksize = settings.blocks_per_chunk
Both of the assignments are done by Main's __init__.
But I think that Chunk has not an is-a but rather a has-a relation with Main so Main should actually be an argument rather than a super class:
class Chunk(object):
def __init__(self, main, pos_in_world_x,pos_in_world_y):
#self.chunksize = settings.blocks_per_chunk
self.prog = main.prog
self.ctx = main.ctx
Any one that creates a Chunk must pass a Main instance.
It is actually difficult to hide information in Python, so here are a few options which don't require inheritance (see jpp's answer for the inheritance option). In general, the code is easier to understand when you pass information explicitly (option 1 below, or inheritance), but there may be cases where you'd prefer the other options.
Option 1: The needed info can simply be passed as additional arguments to Chunk's __init__ (either by passing the prog and ctx values themselves, or by passing the Main class or its instance - depending on whether the needed info is stored as class or instance variables). Here's an example of passing Main as an argument:
class Main():
prog = 1
ctx = 2
def __init__(self):
pass
class Chunk():
def __init__(self, pos_in_world_x, pos_in_world_y, M):
#self.chunksize = settings.blocks_per_chunk
self.prog = M.prog
self.ctx = M.ctx
c = Chunk(3, 4, Main)
print(c.prog) # 1
print(c.ctx) # 2
Option 2: Chunk can access Main's class variables directly:
class Main():
prog = 1
ctx = 2
def __init__(self):
pass
class Chunk():
def __init__(self, pos_in_world_x, pos_in_world_y):
#self.chunksize = settings.blocks_per_chunk
self.prog = Main.prog
self.ctx = Main.ctx
c = Chunk(3, 4)
print(c.prog) # 1
print(c.ctx) # 2
Option 3: Chunk can access the instance variables of the Main instance directly (Main needs to be instantiated before Chunk is instantiated):
class Main():
def __init__(self):
self.prog = 1
self.ctx = 2
class Chunk():
def __init__(self, pos_in_world_x, pos_in_world_y):
#self.chunksize = settings.blocks_per_chunk
self.prog = m.prog
self.ctx = m.ctx
m = Main()
c = Chunk(3, 4)
print(c.prog) # 1
print(c.ctx) # 2
Say I'm importing a library which has some core functionality for the program I'm writing. It looks like:
class dothing(object):
def __init__(self):
# stuff
def main(self):
self.thing = []
self.option = []
How can I modify the contents of its variables, without touching the library itself - in other words, from my local code. Or, how can I modify the function "main"?
I've heard of "monkey patching" but I'm not sure this is the right thing
If you want to alter the main function, you can indeed use monkey patching. This is the preferred strategy if you want to alter how the whole class donothing behaves.
class dothing(object):
def __init__(self):
# stuff
def main(self):
self.thing = []
self.option = []
def my_new_main(self):
print("Hello")
self.thing = {}
self.option = ["Foo"]
donothing.main = my_new_main
dn = donothing()
dn.main()
# Hello
dn.thing
# {}
dn.option
# ["Foo"]
You can also use this strategy to attach new methods to donothing.
donothing.bar = lambda self, x: x + 3
dn.bar(1)
# 4
Define another class that inherits from your original class and override the "main" method as follows:
class doOtherThing(dothing):
def main(self):
self.thing = [1] # this is just a value different from [] in the original "main"
Hi I have staring programming with c and I conld'nt understand value scope in python.
here is my code
class ScenarioEnvironment():
def __init__(self):
print(self)
class report():
config = ScenarioEnvironment()
def __init__(self):
self.config = ScenarioEnvironment()
what happens passing config and config at init()?
and I wonder the value scope which config will be class valuable?
You need to know the differences between class attribute and instance object attribute.
Maybe these codes will help you:
class TestConfig1(object):
config = 1
def __init__(self):
self.config = 2
class TestConfig2(object):
config = 1
def __init__(self):
self.config2 = 2
if __name__ == "__main__":
print TestConfig1.config
t = TestConfig1()
print t.config
t2 = TestConfig2()
print t2.config
print t2.config2
more you can see the python blog.click here
Since your question seems a bit ambiguous, I'll just comment/fix your code:
class ScenarioEnvironment():
def __init__(self,x):
self.x = x # Assigning instance variable x to constructor parameter x.
print(self) # You're printing the object instance.
class report():
# Static variable shared amongst all classes.
config = ScenarioEnvironment(None) # Assigned to new instance of ScenarioEnvironment.
def __init__(self):
# No argument, must pass one (None).
# self.config is to a new ScenarioEnvironment instance.
self.config = ScenarioEnvironment(None)
Lets try out the classes.
Output:
s = ScenarioEnvironment(None)
r = report()
>>> <__main__.ScenarioEnvironment instance at 0x026F4238>
>>> <__main__.ScenarioEnvironment instance at 0x026F4300>
>>> <__main__.ScenarioEnvironment instance at 0x026F4350>
I have a semi-large python app that runs on linux. I am trying to set it up so that i can read a config file at program startup and then save those values for use at any time while the application is running, without re-reading the config file.
So I am trying to load a configValues class in my first modual, test.py. And read the values set. Then in this example read the values again in test2.py.
I never get the values. Can someone help me?
Config.py
class config():
def __init__(self):
configFile = File(myPath)
if configFile.exist():
myXML = str(configFile.openAndRead())
def setupValues(self):
configValues.color = self.getElement('color')
def getElement(self, element):
tree=et.fromstring(self.myXML)
for el in tree.findall('head'):
for ch in el.findall(element):
return ch.text
class configValues():
def __init__(self):
global color
test.py
import config
class test():
def __init__(self):
configObj = config.Config()
configVal = config.configValues()
configObj.setupValues()
print configVal.color
test2.py
import config
class test2():
def __init__(self):
configVal = config.configValues()
print configVal.color
Add a global variable and a function to your config.py. And rather than creating configobj in test1.py and test2.py, you can call this function to get the config object.
configobj = None
def getconfigobj():
global configobj
if not configobj:
configObj = config.Config()
return configobj
Edit as per comment. Does something like the following help(using a single instance for the class)?:-
config.py
class config():
_instance = None
def __new__(cls):
if config._instance:
return config._instance
return super(config, cls).__new__(cls)
def __init__(self, myPath):
configFile = File(myPath)
if configFile.exist():
myXML = str(configFile.openAndRead())
config._dict['instance'] = self
def setupValues(self):
self.color = self.getElement('color')
def getElement(self, element):
tree=et.fromstring(self.myXML)
for el in tree.findall('head'):
for ch in el.findall(element):
return ch.text
test1.py
import config
class test():
def __init__(self):
configObj = config.Config()
configObj.setupValues()
print configObj.color
test2.py
import config
class test2():
def __init__(self):
configObj = config.Config()
print configObj.color
I would not use global variables in this case. You may want to assign the config values as config properties and use it like so:
config.py
class Config:
def __init__(self):
# property of the config class
self.color = 'my default color'
# open your config file ..
def setup_values(self):
# assign new value
self.color = self.get_color()
def get_color(self):
# get values from config xml file ..
return "red"
And then import the config in other module and call the color property:
main.py
from config import Config
class Main:
def __init__(self):
config = Config()
config.setup_values()
color = config.color
print color
Main()
I would also shorten the code with one method less by getting the config values in the constructor instead in additional method "setup_values" like so:
class Config:
def __init__(self):
# property of the config class
self.color = self.get_color()
def get_color(self):
# open your config file ..
# get values from config xml file ..
return "red"
and the main.py should look like:
from config import Config
class Main:
def __init__(self):
config = Config()
color = config.color
print color
Main()
Bear in mind that it is not a good practice to use global variables in your code so the suggested code above may do the job for you.