I want to access a property exist in the self.context using a variable. I have a variable name "prop" and it contains a value and it is already set in the self.context. I am using Flask Restplus framework.
prop = 'binding'
If I try to access this property like below then it gives me an error:
Object is not subscriptable
I want to know if there is any way to get the value? Like doing this:
print(self.context[prop])
I only get one solution don't know if its correct or not, I tried this :
self.context.__getattribute__(prop)
There are two ways to do this, the simplest is using getattr:
getattr(self.context, prop)
This function internally calls __getattribute__ so it's the same as your code, just a little neater.
However, you still have the problem that you probably only want to access some of the context, while not risking editing values set by different parts of your application. A much better way would be to store a dict in context:
self.context.attributes = {}
self.context.attributes["binding"] = False
print(self.context.attributes[prop])
This way, only certain context variables can be accessed and those that are meant to be dynamic don't mess with any used by your application code directly.
Related
I am trying to write a testing program for a python program that takes data, does calculations on it, then puts the output in a class instance object. This object contains several other objects, each with their own attributes. I'm trying to access all the attributes and sub-attributes dynamically with a one size fits all solution, corresponding to elements in a dictionary I wrote to cycle through and get all those attributes for printing onto a test output file.
Edit: this may not be clear from the above but I have a list of the attributes I want, so using something to actually get those attributes is not a problem, although I'm aware python has methods that accomplish this. What I need to do is to be able to get all of those attributes with the same function call, regardless of whether they are top level object attributes or attributes of object attributes.
Python is having some trouble with this - first I tried doing something like this:
for string in attr_dictionary:
...
outputFile.print(outputclass.string)
...
But Python did not like this, and returned an AttributeError
After checking SE, I learned that this is a supposed solution:
for string in attr_dictionary:
...
outputFile.print(getattr(outputclass, string))
...
The only problem is - I want to dynamically access the attributes of objects that are attributes of outputclass. So ideally it would be something like outputclass.objectAttribute.attribute, but this does not work in python. When I use getattr(outputclass, objectAttribute.string), python returns an AttributeError
Any good solution here?
One thing I have thought of trying is creating methods to return those sub-attributes, something like:
class outputObject:
...
def attributeIWant(self,...):
return self.subObject.attributeIWant
...
Even then, it seems like getattr() will return an error because attributeIWant() is supposed to be a function call, it's not actually an attribute. I'm not certain that this is even within the capabilities of Python to make this happen.
Thank you in advance for reading and/or responding, if anyone is familiar with a way to do this it would save me a bunch of refactoring or additional code.
edit: Additional Clarification
The class for example is outputData, and inside that class you could have and instance of the class furtherData, which has the attribute dataIWant:
class outputData:
example: furtherData
example = furtherData()
example.dataIWant = someData
...
with the python getattr I can't access both attributes directly in outputData and attributes of example unless I use separate calls, the attribute of example needs two calls to getattr.
Edit2: I have found a solution I think works for this, see below
I was able to figure this out - I just wrote a quick function that splits the attribute string (for example outputObj.subObj.propertyIWant) then proceeds down the resultant array, calling getattr on each subobject until it reaches the end of the array and returns the actual attribute.
Code:
def obtainAttribute(sample, attributeString: str):
baseObj = sample
attrArray = attributeString.split(".")
for string in attrArray:
if(attrArray.index(string) == (len(attrArray) - 1)):
return getattr(baseObj,string)
else:
baseObj = getattr(baseObj,string)
return "failed"
sample is the object and attributeString is, for example object.subObject.attributeYouWant
I want to use context vars for a similar purpose like in this question and accepted answer: Context variables in Python
That corresponds to f3a() in this example:
import contextvars
user_id = contextvars.ContextVar("user_id_var")
def test():
user_id.set("SOME-DATA")
f2()
def f2():
f3a()
f3b()
def f3a():
print(user_id.get())
def f3b():
ctx = contextvars.copy_context()
for key, value in ctx.items():
if key.name == 'user_id_var':
print(value)
break
test()
However the function needs the user_id global variable to get the value. If it were in a different module, it would need to import it.
My idea was that if a function knows there exists a context and it knows the variable name, that should be all it needs. I wrote the f3b, but as you can see, I have to search all variables, because context vars do not support lookup by name. Lookup by variable is implemented, but if I had the variable, I could get the value directly from it (f3a case)
I'm afraid I do not understand why it was designed the way it was. Why an agreed-upon name is not a key? If a context is set in some kind of framework and then used by application code, those two functions will be in different modules without a common module global var. The examples I could find did not help me. Could somebody please explain the rationale behind the context vars API?
This is the best I worked out to make it actually make sense when I use it:
ctx = {ctx_var.name: {"context_var": ctx_var, "value": value} for ctx_var, value in copy_context().items()}
You can get the value of key user_id by this way
user_id = contextvars.ContextVar("user_id_var")
ctx = contextvars.copy_context()
ctx[user_id]
# or
ctx.get(user_id)
I saw in the official document they have mention something that might related to your concern:
The notion of "current value" deserves special consideration: different asynchronous tasks that exist and execute concurrently may have different values for the same key
and Making Context objects picklable
I would like to use a function's parameter to create dynamic names of dataframes and/or objects in Python. I have about 40 different names so it would be really elegant to do this in a function. Is there a way to do this or do I need to do this via 'dict'? I read that 'exec' is dangerous (not that I could get this to work). SAS has this feature for their macros which is where I am coming from. Here is an example of what I am trying to do (using '#' for illustrative purposes):
def TrainModels (mtype):
model_#mtype = ExtraTreesClassifier()
model_#mtype.fit(X_#mtype, Y_#mtype)
TrainModels ('FirstModel')
TrainModels ('SecondModel')
You could use a dictionary for this:
models = {}
def TrainModels (mtype):
models[mtype] = ExtraTreesClassifier()
models[mtype].fit()
First of all, any name you define within your TrainModels function will be local to that function, so won't be accessible in the rest of your program. So you have to define a global name.
Everything in Python is a dictionary, including the global namespace. You can define a new global name dynamically as follows:
my_name = 'foo'
globals()[my_name] = 'bar'
This is terrible and you should never do it. It adds too much indirection to your code. When someone else (or yourself in 3 months when the code is no longer fresh in your mind) reads the code and see 'foo' used elsewhere, they'll have a hard time figuring out where it came from. Code analysis tools will not be able to help you.
I would use a dict as Milkboat suggested.
I am using QuickFix with Python. On the back of this question, I've explored the SessionID class a bit, but I am mystified by the behavior.
The SessionID class is described here. It is formed of a BeginString, SenderCompID and TargetCompID.
Say my SessionID in string form looks like this: FIX.4.2:LMXTS->TS68.
fix.SessionID().fromString() returns :->
Which if you look, are the three filler characters separating the BeginString, SenderCompID and TargetCompID.
fix.SessionID().getBeginString returns 8=☺ (i.e. the BeginString is nowhere). And the same thing applies to getSenderCompID and getTargetCompID, they return 49=☺ and 56=☺ respectively.
fix.SessionID().getTargetCompID().getValue() returns the empty string ''.
Trying another way, fix.SessionID().fromString('FIX.4.2:LMXTS->TS68') returns None.
I am trying to get these values after the session is created (which I can explicitly see happening when I pass fix.ScreenLogFactory(settings) to the initiator. So I am confused.
The method void onLogon( const SessionID& ) {} in Application.h is fired when the session is logged on, and gives you a reference to a SessionID. You could inspect the SessionID object inside onLogon to see how it behaves.
you can do it any of the quickfix methods after your session is created as the sesionId is one of the parameters.
The first method fired is onCreate so you can potentially store the sesionId in your class var and then reuse if if and when required to retrieve your settings. You can also use the onLogon method as suggested in one of the other answers.
Example below
def onCreate(self, sessionID):
self.session_id = sessionID
target = sessionID.getTargetCompID().getString()
sender = sessionID.getSenderCompID().getString()
It sounds like you're looking at the session directly after creating it, before logging on etc. So that means you're not using a breakpoint in, say, FromApp or ToApp to look at the session properties there. If you do, you get the properties directly i.e. SenderCompID, or TargetCompID.
I cannot find the method SessionID in the objects I use. How do you define your 'fix' object?
I have been messing around with web.py lately and wanted to grab some stuff from a db and its returning me a "Storage" object. an the code i am using to call my info is:
db = web.database(dbn='sqlite', db='sqlfile.sqlite')
sely = db.select('carp', order="id ASC")
when sely runs it drops me out text like so:
<Storage {'lvl': 0, 'symbol': u'formb', 'logged': u'false', 'id': 1, 'display': u'Classic'}>
when you print out sely the storage line comes out. how can i get the dictionary out of this object?
A general Python trick for dealing with unknown APIs is to use the dir builtin. Try dir(sely) in the interpreter to see what member variables and functions are defined for the object you get.
If you see something like __iter__, you can call list(sely) to convert the results to a list, and generally iterate over the object in a loop.
If you see something like __getitem__, then you can index into the object and hope to get a value back.
As a side note, I just tried out your code and I get sely to be a web.utils.IterBetter instance (which returns 0 rows, instead of expected 3 in my case). So I cannot really reproduce your problem (but have problems of my own, so to speak).
db = web.database(dbn='sqlite', db='sqlfile.sqlite')
sely = db.select('carp', order="id ASC").list()
sely would be a list of storages, storage is the same as dict, but you can access arguments with obj.key, instead of obj["key"]. You can do dict(obj) to convert storage into dict.
in windows
return list(db.select('top',what='score',where="name = $id",vars=locals())
is ok. you can get the score‘s value.
but
in ubuntu
you shuld do it like this
db.select('top',what='score',where="name = $id",vars=locals())[0]["score"]
i don't know why but it works in my computer