Python 3 Scope between classes in separate files? - python

I have been researching for ages and cannot find this specific question being asked (so perhaps I am missing something simple!) but I have had trouble separating classes into different .py files.
Scenario:
Main class imports a Settings class file and a Work class file..Settings class populates a list with objects instantiated from an Object class file...
Work class wants to cycle through that list and change values within each of those objects. <-- here is where I come unstuck.
I have tried it by making the values class variables rather than instance. Still I have to import the settings class in the work class in order to write the code to access the value to change. But it wont change the instance of that class within the main class where all these classes are called!
I read an article on Properties. The examples they gave were still examples of different classes within the same file.
Any advice as to what I should be looking at would be greatly appreciated!
This is what I was doing to test it out:
Main File where all will be run from:
import Set_Test
import Test_Code
sting = Set_Test.Settings()
tc = Test_Code.Testy()
ID = sting._settingsID
print(f'Settings ID is: {ID}')
tc.changeVal()
ID = sting._settingsID
print(f'Settings ID is: {ID}')
Set_Test.py:
class Settings:
def __init__(self):
self._settingsID = 1
#property
def settingsID(self):
return self._settingsID
#settingsID.setter
def settingsID(self, value):
self.settingsID = value
Test_Code.py:
import Set_Test
class Testy:
def changeVal(self):
Set_Test.Settings.settingsID = 8

Thanks to stovfl who provided the answer in comments. I managed to decipher what stovfl meant eventually :D
I think!
Well the below code works for anyone who wants to know:
Main:
import Set_Test
import Test_Code
sting = Set_Test.Settings()
tc = Test_Code.Testy()
ID = sting._settingsID
print(f'Settings ID is: {ID}')
tc.changeVal(sting)
ID = sting._settingsID
print(f'Settings ID is: {ID}')
Set_Test.py:
class Settings:
def __init__(self):
self._settingsID = 1
#property
def settingsID(self):
return self._settingsID
#settingsID.setter
def settingsID(self, value):
self._settingsID = value
Test_Code.py
import Set_Test
sting = Set_Test.Settings()
class Testy():
def changeVal(self, sting):
print(sting.settingsID)
sting.settingsID = 8
print(sting.settingsID)

Related

How can I recreate a class object for testing, tried debugging and printing relevant items but can't get it?

I have the following class:
class MessageContext:
def __init__(self, raw_packet, packet_header, message_header, message_index):
self.raw_packet = raw_packet
self.pkthdr = packet_header
self.msghdr = message_header
self.msgidx = message_index
self.msg_seqno = packet_header.seqno + message_index
And a function that creates objects using the above class:
def parsers(data):
...
context = MessageContext(None, PacketAdapter(), msghdr, 0)
self.on_message(rawmsg, context)
I am trying to recreate context, and when i set a breakpoint just after it and print context, I get:
<exchanges.protocols.blahblah.MessageContext object at 0x7337211520>
I have left out quite a bit of code as it is very long, but if any more information is needed I am happy to provide of course.
Here is what I get when I print the arguments of MessageContext:
print(PacketAdapter()) -> <exchanges.blahblah.PacketAdapter object at 0x7f60929e1820>
Following the comments below, the PacketAdapter() class looks like this:
class PacketAdapter:
def __init__(self):
self.seqno = 0

Python parent class modifiable by child class or dynamic attribute?

So I am not even sure if what I want to do is possible but I thought I would ask and find out.
I want to build a chef "databag" via python. This is pretty much just a python dictionary. There are other things that need to happen with this databag that are encapsulated in the Databag class.
Now for the meat of the question...
I want to add key/values to this dictionary but need to build it in a way that is easily extensible. NOTE: the autodict is a class that makes it so you can build a dictionary using dot notation.
Here is what I am trying to do:
databag = Databag(
LogGroup=Sub("xva-${environment}-${uniqueid}-mygroup"),
RunList=[
"mysetup::default",
"consul::client"
]
)
databag.Consul() <-- Trying to add consul key/values to databag
print(databag.to_dict())
print(databag.to_string_list())
So you can see how I add the "consul" key values to the already existing databag object.
Here are the class definitions. I know this is wrong which is why I am here to see if this is even possible.
Databag Class
class Databag(object):
def __init__(self,uniqueid=Ref("uniqueid"),environment=Ref("environment"),LogGroup=None,RunList=[]):
self.databag = autodict()
self.databag.uniqueid = uniqueid
self.databag.environment = environment
self.databag.log.group = LogGroup
self.runlist=RunList
def to_string_list(self):
return self.convert_databag_to_string(self.databag)
def to_dict(self):
return self.databag
def get_runlist(self):
return self.convert_to_runlist_string(self.runlist)
Consul Class
class Consul(Databag):
def __init__(self, LogGroup=None):
if LogGroup == None:
Databag.consul.log.group = Databag.log.group
else:
Databag.consul.log.group = LogGroup
As you can see the Consul class is supposed to access the databag dictionary of the Databag class and add the "consul" variables, almost like an attribute. However, I don't want to add a new function to the databag class every time otherwise that class will end up being very, very large.
I was able to get something like this to work with the following method. Although I am up for an suggestions to get this to work. I just read the help posted on this link:
http://www.qtrac.eu/pyclassmulti.html
EDIT: This method is a lot easier:
Note: This uses the exact same implementation of the old method.
consul.py
from classes.databag.utils import *
class Consul:
def Consul(self, LogGroup=None):
if LogGroup == None:
self.databag.consul.log.group = self.databag.log.group
else:
self.databag.consul.log.group = LogGroup
databag.py
from classes.databag.utils import autodict
from classes.databag import consul
class Databag(consul.Consul):
def __init__(self,uniqueid=Ref("uniqueid"),environment=Ref("environment"),LogGroup=None,RunList=[]):
self.databag = autodict()
self.databag.uniqueid = uniqueid
...
...
Folder Structure
/classes/
databag/
utils.py
databag.py
consul.py
testing.py
---- OLD METHOD -----
How I implemented it
from classes.databag.databag import *
databag = Databag(
LogGroup=Sub("xva-${environment}-${uniqueid}-traefik"),
RunList=[
"mysetup::default",
"consul::client"
]
)
databag.Consul()
print(databag.to_dict())
print(databag.to_string_list())
lib.py
def add_methods_from(*modules):
def decorator(Class):
for module in modules:
for method in getattr(module, "__methods__"):
setattr(Class, method.__name__, method)
return Class
return decorator
def register_method(methods):
def register_method(method):
methods.append(method)
return method
return register_method
databay.py
from classes.databag import lib, consul
#lib.add_methods_from(consul)
class Databag(object):
def __init__(self,uniqueid=Ref("uniqueid"),environment=Ref("environment"),LogGroup=None,RunList=[]):
self.databag = autodict()
self.databag.uniqueid = uniqueid
....
....
consul.py
from classes.databag import lib
__methods__ = []
register_method = lib.register_method(__methods__)
#register_method
def Consul(self, LogGroup=None):
if LogGroup == None:
self.databag.consul.log.group = self.databag.log.group
else:
self.databag.consul.log.group = LogGroup
Folder Structure
/classes/
/databag
lib.py
databag.py
consul.py
utils.py
/testing.py

New Object from objects

I am trying to implement Genetic Algorithm and I am new to python and i am trying to build a Python class Gene with the following as properties
Gene has Portid,trt,days
And a second class Chromosome with 20 Gene objects as its property
Chromosome has gene1,gene2,gene3...gene20
As shown in this diagram UML Diagram Any help please
I have tried
import random
class Gene:
def __init__(self,id):
self.id=id
self.nb_trax=random.randint(1,10)
self.nb_days=random.randint(50,100)
class Chromosome(object):
def __init__(self,object):
self.port[i] = [Gene(id) for i in range (20)]
g=Gene('China')
f=Chromosome(g)
and i get an error
f=Chromosome(g)
File "chrom.py", line 11, in __init__
self.port[i] = [Gene(id) for i in range (20)]
AttributeError: 'Chromosome' object has no attribute 'port'
Try the following code. Python 3 does not need (object) hierarchy for classes. You were also using it as a parameter that you were not using so I also deleted it from there. And the part inside the square bracke3ts [] laready creates the list so you don't need to assign it to self.port[i] but to self.port directly.
import random
class Gene:
def __init__(self, id):
self.id = id
self.nb_trax = random.randint(1, 10)
self.nb_days = random.randint(50, 100)
class Chromosome:
def __init__(self):
self.port = [Gene(id) for id in range(20)]

Python - Retrieving values from methods within other classes

I am trying to teach myself Python and have created a file which runs through various questions sets spread out across classes. At the end of this file I want to summarise all of my raw inputs.
Unfortunately, I am struggling to access these values from a separate class. I have broken my coding down into a test example to demonstrate the structure of my program:
class QuestionSet(object):
next_set = 'first_set'
class ClaimEngine(QuestionSet):
def current_set(self):
last_set = "blank"
while_count = int(0)
quizset = Sets.subsets
ParentSet = QuestionSet()
while ParentSet.next_set != last_set and int(while_count)<50:
quizset[ParentSet.next_set].questioning()
while_count = while_count+1
class FirstSet(QuestionSet):
def questioning(self):
value1 = raw_input("Val1")
QuestionSet.next_set = "second_set"
class SecondSet(QuestionSet):
def questioning(self):
value2 = raw_input("Val2")
QuestionSet.next_set = "summary"
class Summary(QuestionSet):
print "test"
## I need to print a summary of my inputs here ##
## e.g. Print "The answer to value1 was:%r" %value1##
class Sets(object):
subsets = {
'first_set': FirstSet(),
'second_set': SecondSet(),
'summary': Summary()
}
I have tried defining within the Summary each class e.g. 1stSet = FirstSet() and then FirstSet.value1 etc but to no avail.
If anyone has any suggestions on how to retrieve these values that would be great as I have written a massive program full of questions and have fallen at the last hurdle!
Thank you.
The values you have in each function of the classes are not created as class members. For your application you need to create member variables which store the values within the class.
For example:
class FirstSet(QuestionSet):
def questioning(self):
self.value1 = raw_input("Val1")
QuestionSet.next_set = "second_set"
Now value1 is a member variable you can access it.
In the case of the example you have above it would probably be something like the line below to access the value1 from 'first_set'
subsets['first_set'].value1
If you're not familiar with this try
this tutorial

Python - Assigning attributes to a class instance using a for loop and a list

Hi folks I am experimenting with Python (I found pygame.org and wanted to play around) and I am trying to read some settings from a configuration file. I want to be able to change stats on the fly. (So if I wanted to change how hard a fighter hits or how fast a wizard runs then I'd be able to do that.) I was hoping to be able to read from a list and create an attribute for each instance in the list basically this:
for stat in Character.stats:
self.stat = parser.get(self.char_class, stat)
What ends up happening is there is an object with an attribute names 'stat' that contains the last value assigned. What I would LIKE to happen is to have an attribute created for each item in the list, and then get assigned the related value from the config file.
here is more code for context:
class Character(object):
stats = ["level_mod",
"power",
"speed",
"hit",
"evade",
"magic",
"stamina",
"magic_defense",
"intelligence"]
def __init__(self, name, rpg_id):
self.name = name
self.rpg_id = rpg_id
self.__setStats()
def __setStats(self):
parser = SafeConfigParser()
parser.read('char_config.cfg')
for stat in Character.stats:
self.stat = parser.get(self.char_class, stat)
Thanks for your time!
You can use, setattr:
for stat in Character.stats:
setattr(self, stat, parser.get(self.char_class, stat))
Or manually access dict
for stat in Character.stats:
self.__dict__[stat] = parser.get(self.char_class, stat))
You want setattr(obj, attrname, value)
You better re-design that part of the game by adding a Stats class.
class Stats:
STATS = ["level_mod",
"power",
"speed",
"hit",
"evade",
"magic",
"stamina",
"magic_defense",
"intelligence"]
def __init__(self, conf_file=None):
self.__stats = {}
if conf_file is not None:
self.loads_stats_from_file(conf_file)
def load_stats_from_file(self, conf_file):
"""
Here add the pairs <stat_name>:<value>
to the self.__stats dict. For that just parse the config
file like before.
"""
pass
def get_stat(self, stat_name):
return self.__stats[stat_name]
def set_stat(self, stat_name, value):
self.__stats[stat_name] = value
Then you can add a Stats instance to your Character.
class Character(object):
def __init__(self, name, rpg_id):
self.stats = Stats("char_config.cfg")
self.name = name
self.rpg_id = rpg_id
This way you improve usability and decouple the Stats and Character logics. And besides, your problem is reduced from "Adding attributes to an object" to "Adding items to a dictionary".

Categories

Resources