How to initialize an object coming from another class? - python

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.

Related

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

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

Pycharm: property cannot be set

I'm trying to override flask_jsonrpc's formatter method:
from flask_jsonrpc import exceptions
def override_jsonrpc_error_formatter(app):
#property
def json_rpc_format(self):
return ErrorFormatter.format_error(self)
exceptions.Error.json_rpc_format = json_rpc_format
override_jsonrpc_error_formatter function is called in a different file then.
Everything works, but pycharm shows me a warning for the last string, saying: "property json_rpc_format cannot be set". Why is it happening? Do I need to override it in a different way?
So, you import the exceptions from the flask_jsonrpc package.
In the package, you can find these lines:
class Error(Exception):
"""Error class based on the JSON-RPC 2.0 specs
http://groups.google.com/group/json-rpc/web/json-rpc-1-2-proposal
code - number
message - string
data - object
status - number from http://groups.google.com/group/json-rpc/web/json-rpc-over-http JSON-RPC over HTTP Errors section
"""
code = 0
message = None
data = None
status = 200
def __init__(self, message=None, code=None, data=None):
"""Setup the Exception and overwrite the default message
"""
super(Error, self).__init__()
if message is not None:
self.message = message
if code is not None:
self.code = code
if data is not None:
self.data = data
#property
def json_rpc_format(self):
"""Return the Exception data in a format for JSON-RPC
"""
error = {
'name': text_type(self.__class__.__name__),
'code': self.code,
'message': '{0}'.format(text_type(self.message)),
'data': self.data
}
if current_app.config['DEBUG']:
import sys, traceback
error['stack'] = traceback.format_exc()
error['executable'] = sys.executable
return error
So basically, you're trying to overwrite a property of the Error class from the flask_jsonrpc package, which is not allowed, because it's an unsettable property.
If you instead want to overwrite it, I think you should inherit from it using a different class, and either import that directly or connect it back to the module.
E.g.:
class myCustomError(exceptions.Error):
#property
def json_rpc_format(self):
return do_some_custom_logic_here()
You need to read about setters
In you case I would do something like:
class CustomError(Error):
#property
def json_rpc_format(self):
return self._json_rpc_format
#json_rpc_format.setter
def json_rpc_format(self, value):
self._json_rpc_format = value

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.

Extend Python object in run-time using inheritance

I would like to extend an object with new attributes and methods, but in run-time. Basically I would prefer to just inherit and extend a class, but new objects of the base class are not usually created using it's constructor but by using fairly complex function.
Instead of...
from win32com import client
excel = client.Dispatch("Excel.Application")
excel.Visible = 1
excel.Workbooks.Add()
print(excel.Range("A1").value)
...I need something like (obviously broken):
from win32com import client
class Excel(client.CDispatch):
def __init__(self):
self = client.Dispatch("Excel.Application")
def get(self, cell):
return self.Range(cell).value
def show(self):
self.Visible = 1
excel = Excel()
excel.show()
excel.Workbooks.Add() # I want this to be still working
print(excel.get("A1"))
I still would like to be able to use original methods and attributes, but also my new ones. I have trouble wrapping my head around the concept, I am even not sure how to call the principle. Any ideas?
Another way to get desired functionality is like this:
from win32com import client
class Excel():
def __init__(self):
self.excel = client.Dispatch("Excel.Application")
self.Workbooks = self.excel.Workbooks
# I do not really want to repeat all base class
# functionality here to bind it to my new class
def get(self, cell):
return self.excel.Range(cell).value
def show(self):
self.excel.Visible = 1
excel = Excel()
excel.show()
excel.Workbooks.Add()
print(excel.get("A1"))
That works, however requires me to do a lot of lines similar to self.Workbooks = self.excel.Workbooks.
Implementation inheritence is mostly a variant of the composition / delegation pattern. The good news is that Python makes delegation quite easy. I've not tried (not working on Windows) but the following snippet might just work:
from win32com import client
class Excel(object):
def __init__(self):
self._app = client.Dispatch("Excel.Application")
def get(self, cell):
return self._app.Range(cell).value
def show(self):
self._app.Visible = 1
def __getattr__(self, name):
try:
return getattr(self._app, name)
except AttributeError:
raise AttributeError(
"'%s' object has no attribute '%s'" % (type(self).__name__, name))

Categories

Resources