How can you pass a user configurable dict into a class instance - python

I have a class that makes objects allowing me to access properties of an experimental camera system. I have some configuration properties saved in a dict for where certain cameras should be initially located. As these initial settings may vary I cannot hard code them into the class but need them separate in a text file that I access using the json library.
Is there a way to pass the dict into a class so its key value pairs can be used?
Simplified code
import any_dict_01
import json
data = any_dict_01
class dummy(data):
def __init__(self):
self.data = data
def getDict(self):
print(self.data)
a = dummy()
a.getDict()
Working Code
based on hints and advice from karl in the comments under the question I figured out how to do it (I hope karl puts his comments as an answer so I can accept it).
import json
data = 'my_rig.txt'
class dummy:
def __init__(self, data):
self.data = data
def getDict(self):
with open(data) as json_file:
data = json.load(json_file)
print(data)
a =dummy()
theDict = a.getDict(data)

By request:
data = any_dict_01 does not make data be any particular dict defined by the any_dict_01 module. It makes data be another name for that same module.
Anyway, this question isn't really about classes. The way you get information into the __init__ method is the same way that you get information into any ordinary function: by giving it a parameter, and passing the information in as an argument.

Your code would work by fixing the last part like this:
def __init__(self, data):
self.data = data
def getDict(self):
return self.data
a = dummy(data)
theDict=a.getDict()
You can make the dict accessible with dot notation, as if it were a class instance, like this.

class dummy:
def __init__(self, my_dict):
self.my_dict = my_dict

Related

How to initialize an object coming from another class?

I have a function in a class (TableManager) that get the item and a specific field ('body') in DynamoDB.
class TableManager:
def get_body_dynamo(self, item):
get_body = json.loads(item.get('txt_vlr_parm_requ').get('body')) ##dict
return get_body
I need to initialize this 'body' field in another class (S3Connection), but I'm having trouble calling this function inside init.
class S3Connection:
def __init__(self, file, logs):
self.file = file
self.logs = logs
self.versions = None
I need something like this, to use this body I got from Dynamodb and create functions.
class S3Connection:
def __init__(self, file, logs, body_dynamo: TableManager.get_body_dynamo()):
self.body_dynamo = body_dynamo
self.file = file
self.logs = logs
self.versions = None
This way, of course, is giving error (not recognizing what body_dynamo is).
I'm new in programming and Python, so I appreciate any help.

Assignment in python class argument

I don't have much experience with python and probably this is duplicated question.. sorry for that
Let assume I have the following code:
class myclassI:
def __init__(self, key=None, data=None):
self.key = key
self.data= data
class myclassII:
def addInfo(self, key, data)
NewInfo = myclassI(key=key, data=data)
I see this type of call and I was wondering what do we mean by performing "key=key" when we are calling "myclassI"?
Many thanks for any suggestions!

How do I best store API data into a Python class instance variable?

I would like some advice on how to best design a class and it's instance variables. I initialize the class with self.name. However, the main purpose of this class it to retrieve data from an API passing self.name as a parameter, and then parsing the data accordingly. I have a class method called fetch_data(self.name) that makes the API request and returns ALL data. I want to store this data into a class instance variable, and then call other methods on that variable. For example, get_emotions(json), get_personality_traits(json), and get_handle(json), all take the same dictionary as a parameter, assign it to their own local variables, and then manipulate it accordingly.
I know I can make fetch_data(self.name) return data, and then call fetch_data(self.name) within the other methods, assign the return value to a local variable, and manipulate that. The problem is then I will need to call the API 5 times rather than 1, which I can't do for time and money reasons.
So, how do I make the result of fetch_data(self.name) global so that all methods within the class have access to the main data object? I know this is traditionally done in an instance variable, but in this scenario I can't initiliaze the data since I don't have it until after I call fetch_data().
Thank you in advance!
It seems like you just need to do something like this:
class Foo(object):
def __init__(self, name):
self.name = name
self.data = None
def fetch_data(self):
if self.data is None:
# Only call the API once
self.data = self.really_fetch_data()
return self.data
def get_emotions(self):
emotions = self.fetch_data().get("emotions")
...
Why don't you just try to solve this as you described?
For example, you can take this as a starting point:
import json
class APIBundle(object):
def __init__(self, name):
self.name = name
self.data = None
self.update()
def update():
response = json.loads(API_request(self.name))
# Do some parsing on response
self.data = response
def get_emotions():
# Work through current data state
# and filter as desired
result = []
for message in self.data['messages']:
if message.find(':)') != -1:
result.append((message, 'positive'))
if message.find(':(') != -1:
result.append((message, 'negative'))
return result
if __name__ == '__main__':
ab = APIBundle('my-secret-name')
print(self.get_emotions())
Try to do it with self.data=None , or make an instance variable and call whenever you need. writing algorithm will make this thing more complex try to solve issue with inbuilt functions or with algorithm program vulnerability will affect alot.

Can I add methods into def __init__?

Using python 2.7.6, I have been trying to write a class that can extract pieces of xml data from a couple of xml files within a given zip file. I want to be able to use any of the methods in any order once I am working with the class, so wanted the unzip stage to be behind the scenes, in the class.
It is the first time I have really tried to make real use of a class as I am quite new to python, so I am learning as I go.
I defined methods to unzip the data to memory and was using those methods in other methods - then realised it would be horribly inefficient when using multiple methods. Since the unzipping step is necessary for any method in the class, is there a way to build it into the init definition so it is only done once when the class is first created?
Example of what I currently have:
class XMLzip(object):
def __init__(self, xzipfile):
self.xzipfile = xzipfile
def extract_xml1(self):
#extract the xmlfile to a variable
def extract_xml2(self):
#extract xmlfile2 to a variable
def do_stuff(self):
self.extract_xml1()
....
def do_domethingelse(self):
self.extract_xml1()
Is there a way to do something like I have shown below? And if so, what is it called - my searches haven't been very effective.
class XMLzip(object):
def __init__(self, xzipfile):
self.xzipfile = xzipfile
def extract_xml1()
# extract it here
def extract_xml2()
# extract it here
# Now carry on with normal methods
def do_stuff(self):
...
in the __init__ you can do whatever you want in order to initialize your class, in this case look like what you need is something like this
class XMLzip(object):
def __init__(self, xzipfile):
self.xzipfile = xzipfile
self.xml1 = #extract xml1 here
self.xml2 = #extract xml2 here
def do_stuff(self):
...
if you want to do the extract part only once, then do it and save result in a additional attribute in the instance of your class.
I suspect that the extract procedure is very similar, so you can make it a function be inside your class or outside, that is up to your preference, and give additional arguments to handle the specificity, for example something like this
the outside version
def extract_xml_from_zip(zip_file,this_xml):
# extract the request xml file from the given zip_file
return result
class XMLzip(object):
def __init__(self, xzipfile):
self.xzipfile = xzipfile
self.xml1 = extract_xml_from_zip(xzipfile,"xml1")
self.xml2 = extract_xml_from_zip(xzipfile,"xml2")
def do_stuff(self):
...
the inside version
class XMLzip(object):
def __init__(self, xzipfile):
self.xzipfile = xzipfile
self.xml1 = self.extract_xml_from_zip("xml1")
self.xml2 = self.extract_xml_from_zip("xml2")
def extract_xml_from_zip(self,this_xml):
# extract the request xml file from the zip_file in self.xzipfile
return result
def do_stuff(self):
...
You can call any method you have defined in your class in your initializer.
Demo:
>>> class Foo(object):
... def __init__(self):
... self.some_method()
... def some_method(self):
... print('hi')
...
>>> f = Foo()
hi
I take from your question that you need to extract the files only once. Leave your class as is and use your extract methods in __init__ and set the required attributes/variables for the extracted content.
For example
def __init__(self, xzipfile):
self.xzipfile = xzipfile
self.extract1 = self.extract_xml1()
self.extract2 = self.extract_xml2()
This of course requires your extract methods to have a return value, don't forget that.

pygtk gtk.Builder.connect_signals onto multiple objects?

I am updating some code from using libglade to GtkBuilder, which is supposed to be the way of the future.
With gtk.glade, you could call glade_xml.signal_autoconnect(...) repeatedly to connect signals onto objects of different classes corresponding to different windows in the program. However Builder.connect_signals seems to work only once, and (therefore) to give warnings about any handlers that aren't defined in the first class that's passed in.
I realize I can connect them manually but this seems a bit laborious. (Or for that matter I could use some getattr hackery to let it connect them through a proxy to all the objects...)
Is it a bug there's no function to hook up handlers across multiple objects? Or am I missing something?
Someone else has a similar problem http://www.gtkforums.com/about1514.html which I assume means this can't be done.
Here's what I currently have. Feel free to use it, or to suggest something better:
class HandlerFinder(object):
"""Searches for handler implementations across multiple objects.
"""
# See <http://stackoverflow.com/questions/4637792> for why this is
# necessary.
def __init__(self, backing_objects):
self.backing_objects = backing_objects
def __getattr__(self, name):
for o in self.backing_objects:
if hasattr(o, name):
return getattr(o, name)
else:
raise AttributeError("%r not found on any of %r"
% (name, self.backing_objects))
I have been looking for a solution to this for some time and found that it can be done by passing a dict of all the handlers to connect_signals.
The inspect module can extract methods using
inspect.getmembers(instance, predicate=inspect.ismethod
These can then be concatenated into a dictionary using d.update(d3), watching out for duplicate functions such as on_delete.
Example code:
import inspect
...
handlers = {}
for c in [win2, win3, win4, self]: # self is the main window
methods = inspect.getmembers(c, predicate=inspect.ismethod)
handlers.update(methods)
builder.connect_signals(handlers)
This will not pick up alias method names declared using #alias. For an example of how to do that, see the code for Builder.py, at def dict_from_callback_obj.
I'm only a novice but this is what I do, maybe it can inspire;-)
I instantiate the major components from a 'control' and pass the builder object so that the instantiated object can make use of any of the builder objects (mainwindow in example) or add to the builder (aboutDialog example). I also pass a dictionary (dic) where each component adds "signals" to it.
Then the 'connect_signals(dic)' is executed.
Of course I need to do some manual signal connecting when I need to pass user arguments to the callback method, but those are few.
#modules.control.py
class Control:
def __init__(self):
# Load the builder obj
guibuilder = gtk.Builder()
guibuilder.add_from_file("gui/mainwindow.ui")
# Create a dictionnary to store signal from loaded components
dic = {}
# Instanciate the components...
aboutdialog = modules.aboutdialog.AboutDialog(guibuilder, dic)
mainwin = modules.mainwindow.MainWindow(guibuilder, dic, self)
...
guibuilder.connect_signals(dic)
del dic
#modules/aboutdialog.py
class AboutDialog:
def __init__(self, builder, dic):
dic["on_OpenAboutWindow_activate"] = self.on_OpenAboutWindow_activate
self.builder = builder
def on_OpenAboutWindow_activate(self, menu_item):
self.builder.add_from_file("gui/aboutdialog.ui")
self.aboutdialog = self.builder.get_object("aboutdialog")
self.aboutdialog.run()
self.aboutdialog.destroy()
#modules/mainwindow.py
class MainWindow:
def __init__(self, builder, dic, controller):
self.control = controller
# get gui xml and/or signals
dic["on_file_new_activate"] = self.control.newFile
dic["on_file_open_activate"] = self.control.openFile
dic["on_file_save_activate"] = self.control.saveFile
dic["on_file_close_activate"] = self.control.closeFile
...
# get needed gui objects
self.mainWindow = builder.get_object("mainWindow")
...
Edit: alternative to auto attach signals to callbacks:
Untested code
def start_element(name, attrs):
if name == "signal":
if attrs["handler"]:
handler = attrs["handler"]
#Insert code to verify if handler is part of the collection
#we want.
self.handlerList.append(handler)
def extractSignals(uiFile)
import xml.parsers.expat
p = xml.parsers.expat.ParserCreate()
p.StartElementHandler = self.start_element
p.ParseFile(uiFile)
self.handlerList = []
extractSignals(uiFile)
for handler in handlerList:
dic[handler] = eval(''. join(["self.", handler, "_cb"]))
builder.connect_signals
({
"on_window_destroy" : gtk.main_quit,
"on_buttonQuit_clicked" : gtk.main_quit
})

Categories

Resources