0

Here is the use case.

class EvaluateCustomMethod(object):
 faker = Faker()
 def __init__(self, custom_method, cardinality=1):
 self.custom_method = custom_method
 self.cardinality = cardinality
 @property 
 def random_first_name(self):
 return self.faker.first.name()
 def call_method_n_times(self):
 return [getattr(self, self.custom_method) \
 for _ in range(self.cardinality)]
f = EvaluateCustomMethod('random_first_name', 1)
f.call_method_n_times()

I am trying to find a way where I do not have to make a method call after instantiating an object and achieve my goal directly when I create an instance.

My ultimate goal is this:

 {"test" : {"name" : EvaluateCustomMethod('random_first_name', 1)}}

This is linked to a previous question

asked May 12, 2017 at 21:30
2
  • Do not hesitate to mention that this question is linked to another one. This is a common practice on SO. Commented May 12, 2017 at 21:33
  • You shouldn't do this even if you can (by overriding the __new__ method). Just refactor EvaluateCustomMethod into a function. Commented May 12, 2017 at 21:55

1 Answer 1

1

The answer which follows is a don't, since wanting to do what is proposed is very likely to be a strong signal of refactoring need.

One possibility is to use the constructor __new__, so as to determine what is going to be returned when you instantiate the class. As follows

class EvaluateCustomMethod(object):
 faker = Faker()
 def __new__(cls, custom_method, cardinality=1): 
 instance = super(EvaluateCustomMethod, cls).__new__(cls)
 instance.custom_method = custom_method
 instance.cardinality = cardinality
 return instance.call_method_n_times()
 @property 
 def random_first_name(self):
 return self.faker.first.name()
 def call_method_n_times(self):
 return [getattr(self, self.custom_method) \
 for _ in range(self.cardinality)]

Which would return

>>> EvaluateCustomMethod('random_first_name', 1)
['John']
>>> {"test" : {"name" : EvaluateCustomMethod('random_first_name', 1)}}
{"test" : {"name" : ['Jack']}}


But actually, overriding __new__ like so is so discouraged, that what you may want to do, more classically, is

class EvaluateCustomMethod(object):
 faker = Faker()
 def __init__(self, custom_method, cardinality=1):
 self.custom_method = custom_method
 self.cardinality = cardinality
 @property 
 def random_first_name(self):
 return self.faker.first.name()
 def call_method_n_times(self):
 return [getattr(self, self.custom_method) \
 for _ in range(self.cardinality)]
 def __call__(self):
 return self.call_method_n_times()

Which returns the same thing, but doing exactly what one thinks it does

>>> EvaluateCustomMethod('random_first_name', 1)
['Jacques']
>>> {"test" : {"name" : EvaluateCustomMethod('random_first_name', 1)()}}
{"test" : {"name" : ['Richard']}}
answered May 12, 2017 at 21:52
Sign up to request clarification or add additional context in comments.

4 Comments

That is what I was looking for. If you do not mind can you please add some comments explaining the logic. I am very new to OP this will help others like me. Appreciate your quick response.
@new_kid_07 Although I won't downvote the answer(since it answers what you want), as it's obvious that you're very new to OP, this is definitely something you don't want to do. You should just refactor your code to be a function. That's why we have them!
@new. I definitly agree with rantanplan.
@new. I recommend you to read Python: new magic method explained. Briefly, the idea is that when you instantiate your class, i.e. foo = Foo(), (almost) instantaneously, written on your own or not, __new__ is called and returns something: an object with methodes and attributes attached. When one override __new__, as above, we make the class actually returning what we exactly tell it to return. In our case, it returns the list returned by the methode you choose to call.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.