1

Obs: Of course I could just create a method that validate, and call this method inside all my other methods. But I wonder if it's posible to do something I've been thinking for a while.

WHAT I NEED:

I have a class where all my methods should verify if the parameter (an object) that it receives is not None and if it has a specific method. Let's make it simple.

I wonder if there is something simple like the following code.

HERE IS AN EXAMPLE:

def validate(obj):
    return not obj or obj.can_validate()

class MyClass:

    def __init__(self):
        pass

    @validate(obj)
    def my_method_1(self, obj):
        print(obj)

    @validate(obj)
    def my_method_2(self, obj):
        print(obj)

    @validate(obj)
    def my_method_3(self, obj):
        print(obj)


class Validator1:

    def __init__(self):
        pass

class Validator2:

    def __init__(self):
        pass

    def can_validate(self):
        pass

my_class = MyClass()

obj_1 = None
obj_2 = Validator1()
obj_3 = Validator2()

print(x.my_method_1(obj_1))
print(x.my_method_2(obj_2))
print(x.my_method_3(obj_3))

# The output would be something like this>>
# output:
# <empty line because obj_1 is None>
# <empty line because obj_2 has no method can_validate()>
# __Class__...something <since it's not none and has can_validate() method>

If there isn't anything similar to that, what should be most clean and correct way to do that, avoiding code repetition and "a ton of code"?

yurisnm
  • 1,630
  • 13
  • 29
  • 1
    You add validation all the methods of a class using one of the ways shown in the accepted answer to the question [How to make built-in containers (sets, dicts, lists) thread safe?](https://stackoverflow.com/questions/13610654/how-to-make-built-in-containers-sets-dicts-lists-thread-safe) which would also for work for user-defined classes. The author of the answer prefers using a class decorator. – martineau Mar 22 '19 at 18:09
  • I almost got a stroke reading that code, but makes a lot of sense, thanks a lot for showing me that man. Maybe is even aplicable in my main "complete problem". – yurisnm Mar 22 '19 at 20:19
  • Yeah, the accepted answer to the linked question pretty long (and deep). Class decorators by themselves aren't exactly rocket science though, so I'd suggest focusing on just that one aspect of the answer. – martineau Mar 22 '19 at 20:27

1 Answers1

1

With minimal changes to your existing code:

def validate(func):
    def modified(self, obj):
        if obj and hasattr(obj, 'can_validate'):
            return func(self, obj)
        return None  # None will be printed. Change it to '' to print empty line
    return modified


class MyClass:

    def __init__(self):
        pass

    @validate
    def my_method_1(self, obj):
        print(obj)

    @validate
    def my_method_2(self, obj):
        print(obj)

    @validate
    def my_method_3(self, obj):
        print(obj)


class Validator1:

    def __init__(self):
        pass

class Validator2:

    def __init__(self):
        pass

    def can_validate(self):
        pass

x = MyClass()

obj_1 = None
obj_2 = Validator1()
obj_3 = Validator2()

print(x.my_method_1(obj_1))
print(x.my_method_2(obj_2))
print(x.my_method_3(obj_3))

output:

None
None
<__main__.Validator2 object at 0x7f6185ca9e10>
None
sanyassh
  • 8,100
  • 13
  • 36
  • 70