How to always call a class method, forcefully, on return in python
I have a
class ReportEntry(object): def __init__(self): # Many attributes defined here ... # Lot many setattr/getattr here def validate(self): # Lot of validation code in here return self
Multiple other classes maintain
has-a relation with
class A(object): def test1(self): t1 = ReportEntry() # Assign the attribute values to t1 return t1.validate() def test2(self): t2 = ReportEntry() # Assign the attribute values to t2 return t2.validate()
And there are multiple such classes as A.
I need to enforce each
ReportEntry class instance to call
return or maybe just before
Basically, no instance of
ReportEntry should escape validation since the final report generation will fail if something is missing.
How may I achieve that ?
You can write a class decorator:
import inspect def validate_entries(cls): def validator(fnc): # this is a function decorator ... def wrapper(*args, **kwargs): rval = fnc(*args, **kwargs) if isinstance(rval, ReportEntry): # print('validating') return rval.validate() return rval return wrapper for name, f in inspect.getmembers(cls, predicate=inspect.isfunction): setattr(cls, name, validator(f)) # .. that we apply to all functions return cls
Now you can define all
@validate_entries class A(object): # ...
This will validate any
ReportEntry that is returned by any of
Python's Instance, Class, and Static Methods Demystified – Real , class MyClass: def method(self): return 'instance method called', self @classmethod def Here's what happens when we call an instance method: Notice how Python automatically passes the class as the first argument to the function when The classmethod () method returns a class method for the given function. The syntax of classmethod () method is: classmethod () is considered un-Pythonic so in newer Python versions, you can use the @classmethod decorator for classmethod definition. @classmethod def func (cls, args)
One approach that I could think of is to define
__exit__ methods where
validate is called upon
class ReportEntry(object): def __enter__(self): return self def __init__(self): # Many attributes defined here ... # Lot many setattr/getattr here def validate(self): # Lot of validation code in here return self def __exit__(self, a,b,c): self.validate() return True # And then use it as with ReportEntry() as report: ...
But again, this will be enforced only when used
with ReportEntry() as report:
2. Built-in Functions, Note that classes are callable (calling a class returns a new instance); instances are If object is not an object of the given type, the function always returns false. by file, but if the flush keyword argument is true, the stream is forcibly flushed. Therefore, you can't force an implementation of your abstract method to be a regular, class or static method, and arguably you shouldn't. Starting with Python 3 (this won't work as you would expect in Python 2, see issue5867 ), it's now possible to use the @staticmethod and @classmethod decorators on top of @abstractmethod :
There are two ways I can think about to go about this. I cannot say more without knowing more implementation details:
Decorate your methods: Where every return instance is run through the decorator function. You may want to put this as a stand-alone function or part of a class depending on your specific use case.
def validate(func): return func().validate() class A(object): @validate def test1(self): t1 = ReportEntry() # Assign the attribute values to t1 return t1 @validate def test2(self): t2 = ReportEntry() # Assign the attribute values to t2 return t2
Updating the __setattr__ and decorate your class:
def always_validate(cls): # save the old set attribute method old_setattr = getattr(cls, '__setattr__', None) def __setattr__(self, name, value): # set the attribute validate(name, value) old_setattr(self, name, value) cls.__setattr__ = __setattr__ return cls
and then you could decorate your ReportEntry:
@alway_validate class ReportEntry(object): ...
Built-in Functions, Note that classes are callable (calling a class returns a new instance); instances This is always the dictionary of the current module (inside a function or method, by file, but if the flush keyword argument is true, the stream is forcibly flushed. Instance, Class, and Static Methods — An Overview Let’s begin by writing a (Python 3) class that contains simple examples for all three method types: class MyClass : def method ( self ): return 'instance method called' , self @classmethod def classmethod ( cls ): return 'class method called' , cls @staticmethod def staticmethod (): return
9. Classes, __doc__ is also a valid attribute, returning the docstring belonging to the The instantiation operation (“calling” a class object) creates an empty object. __init__() method, class instantiation automatically invokes __init__() ** * The methods that are test scenarios start with test_ to help python discover them easily. In Python, there are two ways of defining static methods within a class. In this tutorial we will learn about the class __del__ method in Python. b import classa class classb: def method_1(): = classa() a.
Python - Call function from another function, When the called function completes its execution and returns then the calling function is popped from the Python code to demonstrate calling parent class. It is a mixture of the class mechanisms found in C++ and Modula-3. Python classes provide all the standard features of Object Oriented Programming: the class inheritance mechanism allows multiple base classes, a derived class can override any methods of its base class or classes, and a method can call the method of a base class with the same name.