Execute python method from a string - python-3.x

I have a string that has the method name and value in it. Currently, I'm using the following implementation which works but doesn't seem elegant. Is there a better way to implement this?
class ObjectResolver:
def methodResolver(self, value):
"""Some logic here"""
print(value)
objectResolver = ObjectResolver()
channel = 'methodResolver(helloWorld)'
findValue = channel.strip().find('(')
objectMethod = channel.strip()[:findValue]
attribute = channel.strip()[findValue:][1:-1]
channelResolver = getattr(objectResolver, objectMethod)(attribute)
Output:
helloWorld

You can use eval() or exec()
class ObjectResolver:
def methodResolver(self, value):
"""Some logic here"""
print(value)
objectResolver = ObjectResolver()
// Something like this...
channel = eval('methodResolver')(helloWorld)
// OR
exec('channel = "methodResolver(helloWorld)"')
findValue = channel.strip().find('(')
objectMethod = channel.strip()[:findValue]
attribute = channel.strip()[findValue:][1:-1]
channelResolver = getattr(objectResolver, objectMethod)(attribute)
Learn more about eval and exec

The best method I found is to use eval here and specifically to my question above, the implementation is as follows:
class ObjectResolver:
def methodResolver(self, value):
"""Some logic here"""
print(value)
objectResolver = ObjectResolver()
channel = "methodResolver('helloWorld')"
handlers = dict(methodResolver=objectResolver.methodResolver)
eval(channel, handlers)

Related

How mock a method with parameters and return an iterable in python

I need to test this function with a unit test:
def nlp_extraction(texts, nlp=None):
extr = []
for doc in nlp.pipe([texts]):
extr.append(list([ent.label_, ent.text]) for ent in doc.ents)
extracao = [list(extr[i]) for i in range(len(extr))]
extracao = list(chain.from_iterable(extracao))
extracao = " ".join([item[1] for item in extracao])
return [texts, extracao]
I wrote, inicialy, this test and worked:
def test_nlp_extraction_entrada_correta():
nlp = loadModel('ner_extract_ingredients')
result_reference = ['xilitol', 'xilitol']
texts = 'xilitol'
result = nlp_extraction(texts, nlp)
assert result == result_reference
But in this test I need to load the model. As this is an unit test, I would like to mock the responses, thus load an external model can be disable. I am trying something like this (and a combination of the lines commented in the code):
def test_nlp_extraction_entrada_correta():
texts = 'xilitol'
doc = Mock(name="DOC")
ents = Mock(name="ENTS", label_='xilitol', text="xilitol")
doc.ents = [ents]
from nextmock import Mock
nlp = Mock()
nlp_mock = Mock()
nlp.with_args([texts]).returns([doc])
nlp_mock.pipe = nlp([texts])
# nlp_mock.pipe.with_args([texts]).returns(doc)
# nlp_mock.pipe = [Mock(return_value=doc)]
result = nlp_extraction(texts, nlp=nlp_mock)
assert result == result_reference
But an error always raise, saying that nlp.pipe([texts]) mock object is not iterable. So, I need to mock this part nlp.pipe([texts]) and return the doc object. How I can do this? Something I am missing in the proccess, can someone help me.
As Cpt.Hook said in comments, the solution was achieved using nlp.pipe.return_value = [doc].

How can I make this body of code through a for loop?

So, I'm trying to get this code to work in a cleaner way, mainly, through the use of a for loop, but having a really hard time trying to do so. I haven't been able to make a loop that assigns each value of the dictionary to a correspondent variable, so it can be used in the class. For context, the dictionary contains values obtained from another class, I just put those in the dict and sent it to this class, so I don't need to calculate those again.
def get_ipr_data(self):
self.reservoir_result_dict = ReservoirDataFrame.reservoir_result_dict
self.pb = self.reservoir_result_dict.get("pb")
self.rs = self.reservoir_result_dict.get("rs")
self.bo = self.reservoir_result_dict.get("bo")
self.uo = self.reservoir_result_dict.get("uo")
self.re = self.reservoir_result_dict.get("re")
self.j_index = self.reservoir_result_dict.get("j_index")
self.q_max = self.reservoir_result_dict.get("q_max")
self.pws = self.reservoir_result_dict.get("pws")
self.qb = self.reservoir_result_dict.get("qb")
You can use setattr function
for name in ["pb", "rs", "bo", "uo", "re", "j_index", "q_max", "pws", "qb"]:
setattr(self, name, self.reservoir_result_dict.get(name))
Documentation of setattr:
https://docs.python.org/3/library/functions.html#setattr
Delegating attributes is done by defining the __getattr__ method. You should store the dictionary only and then define __getattr__.
class Foo:
...
def get_ipr_data(self):
self.reservoir_result_dict = ReservoirDataFrame.reservoir_result_dict
def __getattr__(self, item):
return self.reservoir_result_dict[item]

sub-classing a peewee field type to add behavior

I am trying to add the required behavior to a CharFiled or TextField so I can store a list of lists and retrieve it as a list of lists again. I am not asking for a solution rather I would like to see an example where a subclassing of an already supported field type is done as I didn't find any in the documentation or the Internet.
Do I have to do it as explained in the documents for creating a custom type?
for example:
class mylistoflists(TextField):
if yes, then what do I have to assign to field_type?
Example code (see tests/fields.py for full example):
class ListField(TextField):
def db_value(self, value):
return ','.join(value) if value else ''
def python_value(self, value):
return value.split(',') if value else []
class Todo(TestModel):
content = TextField()
tags = ListField()
class TestCustomField(ModelTestCase):
requires = [Todo]
def test_custom_field(self):
t1 = Todo.create(content='t1', tags=['t1-a', 't1-b'])
t2 = Todo.create(content='t2', tags=[])
t1_db = Todo.get(Todo.id == t1.id)
self.assertEqual(t1_db.tags, ['t1-a', 't1-b'])
t2_db = Todo.get(Todo.id == t2.id)
self.assertEqual(t2_db.tags, [])
t1_db = Todo.get(Todo.tags == Value(['t1-a', 't1-b'], unpack=False))
self.assertEqual(t1_db.id, t1.id)

obtain value from Key/value in map array groovy

I have code like this:
def options = JsonPath.read(prev.getResponseDataAsString(), '$.options')
def randomOption = options.get(RandomUtils.nextInt(0, options.size()))
def code = randomOption.get("code")
vars.put('code1', code)
def values = randomOption.get('values')
def randomValue = values.get(RandomUtils.nextInt(0, values.size())) as
String
def val = randomValue['value']
vars.put('randomValue', randomValue)
vars.put('ValueF', val).
In Random Variable i am getting value as [label:Red, value:8] . I need to fetch the value of Value=8
Youre trying to invoke
vars.put('ValueF', [label:Red, value:8])
which is put(String, Map)
JMeterVariables have no such method https://jmeter.apache.org/api/org/apache/jmeter/threads/JMeterVariables.html
you can use putObject() which accepts String as key and Object as value:
vars.putObject('ValueF', val)

Trigger a function when any property of an object changes with RxPy

In RxPy, is there anything similar to INotifyPropertyChanged in .NET framework mentioned here? I'm trying to add an observer to an object, so that any property of the object changes, a function will be called.
Try something like this:
class A(object):
def __init__(self):
self._my_attr = None
self.property_changed = Subject()
...
#property
def my_attr(self):
return self._my_attr
#my_attr.setter
def my_attr(self, value):
if value != self._my_attr:
self._my_attr = value
self.property_changed.on_next(('my_attr', value))
a = A()
a.property_changed.subscribe(print)
a.my_attr = 1
a.my_attr = 3

Resources