문제

I'm refactoring some code, and I thought I could use a bit of Reflection! So, I have this for now:

def f(self, clazz):
    [...]
    boolean = False
    if hasattr(clazz_instace, 'some_attribute'):
        setattr(clazz_instace, 'some_attribute', True)
        boolean = True

    if boolean:
        result = getattr(clazz_instace, 'another_method')(None, request=request)
        return result['objects']

    sorted_objects = getattr(clazz_instace, 'One_more_method')(request)
    result = getattr(clazz_instace, 'another_method')(sorted_objects, request=request)

    return [...]

My question is about the strings I used to indicate which method I'm searching for regarding to the clazz_instance. I'd like to know if there's another and very best way to do what I did (In a dinamic way to be specific)? I mean, intead of putting method's name like strings directly as I did, would be really nice if I could verify dinamically those methods, differently.

Could you give some nice ideas? How would you do it?

Thanks in advance!!!

도움이 되었습니까?

해결책

An instance's method is nothing more than a function object stored in the instace's __dict__. This said, you are doing correct to find them, except that maybe, the class indeed has the attribute corresponding to your argument string, but is not a function, is just another type instead.

If you depend on this, I recommend you refactor the instance's function looking code into a helper method:

import types
def instance_has_method(instance, name):
    try:
        attr = getattr(instance, name)
        return isinstance(attr, types.FunctionType)
    except AttributeError:
        return False

Once you have this function, your code will be more concise because now you're sure that the attribute is indeed a function and can be callable.

The code above checks if the attribute is a function. If you want something wider, you can check if it's a callable like this: return hasattr(attr, '__call__').

In python, this is basically how you check for attributes inside classes. I don't think there's nothing wrong with your approach and not another more clever way to do reflection.

Hope this helps!

다른 팁

It's not easy to understand what you are trying to achieve.

getattr(clazz_instace, 'One_more_method')(request) is just a fancy way to say clazz_instace.One_more_method(request).

Use of getattr is reasonable when you don't know the method name in advance, that is, if your method name is variable.

Also, setattr(clazz_instace, 'some_method_inside_this_class', True) turns alleged some_method_inside_this_class into a scalar attribute inside that class, having a True value. Probably this is not what you planned to have.

My best effort to understand your code is this:

def f(clazz):
  # if clazz is capable of better_processing, use it:
  if hasattr(clazz, 'better_processing'):
    return clazz.better_processing(...)
  else:
    return clazz.basic_processing(...)

BTW what getattr gives you is a callable method, you can directly use it, like this:

method = getattr(clazz, 'better_method', clazz.default_method)
# if 'better_method' was available, it was returned by getattr;
# if not, the default method was returned.
return method(clazz_instance, some_data...)
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top