Child class defined for any generic parent class [duplicate] - python

This question already has answers here:
What is a mixin and why is it useful?
(18 answers)
Closed 1 year ago.
I want to define a simple child class that inherits all of the parent's methods and introduces some new ones. The caveat: I don't want to have to specify what the parent class is, as I want this child class to be compatible with a broad set of classes. Is there a way to do this?
If not, then what is the best way to create a new class that inherits all the methods from any other class and introduces new methods?

What you're looking for is typically referred to as a mixin. Take these classes for example.
class FooBase:
def data(self):
return "foo"
class BarBase:
def data(self):
return "bar"
Both define data method but are themselves different classes. If we wanted to provide some mixin class that can print the value from data we could do so like this:
from abc import ABC, abstractmethod
class PrintDataMixin(ABC):
#abstractmethod
def data(self):
pass
def print_data(self):
print(self.data())
Here we're saying that the PrintDataMixin mixin can be applied to any class that has a data method implemented. FooBase and BarBase could have completely different sets of methods defined, but as long as they have the data method defined they will satisfy usage with PrintDataMixin.
Example usage for extending FooBase and BarBase with this mixin:
class FooImpl(FooBase, PrintDataMixin):
pass
class BarImpl(BarBase, PrintDataMixin):
pass
FooImpl().print_data()
BarImpl().print_data()
foo
bar
Update:
You could try to do this more generically any point you want, but in general I find dynamic classes like that hard to work with especially when you need to debug the application. It also makes it harder for static analyzers like mypy to determine if you are using classes correctly.
It's much easier to determine what's going on when classes are well defined in the source.
To dynamically create a class with a mixin applied you could do something like this:
def class_of(*cls):
class NewClass(*cls):
pass
return NewClass
class_of(BaseClass, MixinClass)(*args, **kwargs).print_data()

Related

How to create an abstract base class (generally a parent class) that requires its children to have a specific method which sets a specific property?

I want to define an abstract base class, called ParentClass. I want every child class of ParentClass to have a method called "fit" that defines a property "required". If someone tries to create a child class which does not have the "required" property within its fit method, I want an error to be created when the object's fit method is called. I am having trouble doing this.
The context is that I want to create a Parent class, abstract or otherwise, that requires its children to behave in a certain way and have certain properties so that I can trust them to behave in certain ways no matter who is creating children classes. I have found similar questions, but nothing precisely like what I am asking.
My naive attempt was something like the following:
class ParentClass(ABC):
#abstractmethod
def fit(self):
self.required = True
class ChildClass(ParentClass):
def __init__(self):
pass
def fit(self):
self.required = True
class ChildClass2(ParentClass):
def __init__(self):
pass
def fit(self):
self.not_essential = True
This doesn't work, but if possible I would like to refactor ParentClass in such a way that if someone runs:
>> b = ChildClass()
>> b.fit()
everything works fine, but if someone tries to run
>> b2 = ChildClass2()
>> b2.fit()
an error is thrown because the fit method of ChildClass2 doesn't define "required".
Is this possible in Python?
A related question is whether there is a better way to think about structuring my problem. Perhaps there is a better paradigm to achieve what I want? I understand that I can force child classes to have certain methods defined. A clunky way to achieve what I want is to have every property I want to be defined to be returned by a required method, but this feels very clunky, particularly if the number of properties I want to enforce as part of a standard becomes rather large.

pythonic way to expose user override hooks

Note: although my particular use is Flask related, I think the question is more general.
I am building a Flask web application meant to be customized by the user. For example, the user is expected to provide a concrete subclass of a DatabaseInterface and may add to the list of certain ModelObjects that the application knows how to handle.
What is the best way to expose the various hooks to users, and indicate required and optional status? 'Best' here primarily means most 'pythonic', or "easiest for python users to grasp", but other criteria like not causing headaches down the road are certainly worth mentioning.
Some approaches I've considered:
Rely solely on documentation
Create a template file with documented overrides, much like default config files for many servers. E.g.
app = mycode.get_app()
##Add your list of extra foo classes here
#app.extra_foos = []
Create a UserOverrides class with an attr/method for each of the hooks; possibly split into RequiredOverrides and OptionalOverrides
Create an empty class with unimplemented methods that the user must subclass into a concrete instance
One method is by using abstract base classes (abc module). For example, you can define an ABC with abstract methods that must be overridden by child classes like this:
from abc import ABC
class MyClass(ABC): # inherit from ABC
def __init__(self):
pass
#abstractmethod
def some_method(self, args):
# must be overridden by child class
pass
You would then implement a child class like:
class MyChild(MyClass):
# uses parent's __init__ by default
def some_method(self, args):
# overrides the abstract method
You can specify what everything needs to do in the overridden methods with documentation. There are also decorators for abstract properties, class methods, and static methods. Attempting to instantiate an ABC that does not have all of its abstract methods/properties overridden will result in an error.
Inheritance. Is. Bad.
This is especially true in Python, which gives you a nice precedent to avoid the issue. Consider the following code:
len({1,2,3}) # set with length 3
len([1,2,3]) # list with length 3
len((1,2,3)) # tuple with length 3
Which is cool and all for the built-in data structures, but what if you want to make your own data structure and have it work with Python's len? Simple:
class Duple(object):
def __init__(self, fst, snd):
super(Duple, self).__init__()
self.fst = fst
self.snd = snd
def __len__():
return 2
A Duple is a two-element (only) data structure (calling it with more or fewer arguments raises) and now works with len:
len(Duple(1,2)) # 2
Which is exactly how you should do this:
def foo(arg):
return arg.__foo__()
Any class that wants to work with your foo function just implements the __foo__ magic method, which is how len works under the hood.

Static method overloading [duplicate]

This question already has answers here:
Overriding a static method in python
(3 answers)
Closed 6 years ago.
Suppose we declare a static method with same name in different classes. Is it possible?
If it is, then how and which function will be called?
class abc:
#staticmethod
def xyz():
print 'class_abc'
class abc1:
#staticmethod
def xyz():
print 'class_abc1'
class abc2:
#staticmethod
def xyz():
print 'class_abc2'
So what's the output and how we can call different functions of different classes?
You are having three classes with xyz() function in each class. But there is no relationship in these classes as they are not inheriting each other. So the answer is simple: xyz() will be called of the class which is calling the method.
For example: abc.xyz() will call the xyz() function of abc class. Similarly you can make call to ab1 and abc2's function as: abc1.xyz() and abc2.xyz().
You seem to be misunderstanding things. Classes introduce a separate namespace for themselves so, it is completely possible to create functions with the same name in different classes. These functions are not related in any other way other than their similar name.
Running <classname>.xyz() simply calls xyz() and prints the corresponding message.
Even if there was a relationship between the class, i.e a sub-classing relationship of the form:
class abc:
#staticmethod
def xyz():
print 'class_abc'
class abc1(abc):
#staticmethod
def xyz():
print 'class_abc1'
class abc2(abc1):
#staticmethod
def xyz():
print 'class_abc2'
The most recent definition of xyz will override previously existing entries for it and the effect would be the same, that is abc2.xyz() would print class_abc2, abc1.xyz() prints class_abc1 and so on.
Also, do note, you're using Python 2.x but aren't actually inheriting from object. This won't create a class in the sense most people are aware with today, take a look at What is the difference between old style and new style classes in Python? to get a better idea of what this entails.
Suppose we declare a static method with same name in different is it possible?
Yes
If it is possible then how and which function will be called.?
It's possible because classes have their own scope. Python treats each static method in your example differently. And even if your classes where related, such as in #Jim Fasarakis-Hilliard example, the current method would override the last method.
Each method will be called uniquely because each class is unrelated in your example(except for all of the classes being of type class).

Ordering class methods without instantiation

Related: inspect.getmembers in order?
Background: I'm trying to build a tool that creates a Python file according to a certain specification. One option is to give, as input, a Python module that contains an abstract class declaration, and creates a base class that inherits that abstract class but also adds a default implementation to all abstract methods.
For example: say I have the following file, called Abstract.py that contains the following:
class Abstract(object):
__metaclass__ = ABCMeta
#abstractmethod
def first(self):
pass
#abstractmethod
def second(self):
pass
So then the output of my tool would be a file called BaseClass.py that contains:
class BaseClass(Abstract):
def first(self):
pass
def second(self):
pass
I want the methods in the BaseClass to be in the same order as in Abstract.
My question is: Is there a way to sort the methods according to their appearance without relying on built-in method comparison (which is based on memory address comparison)? I'm also hoping to avoid any kind of file-parsing, if possible.
Please note that I cannot create an instance of Abstract so the solution mentioned in the above related question will not work for me.
At the time of class creation in Python2 (that is, when the interpreter just get pass the class body when running a file, which happens in sequence) - the Class itself is created as an object. At this point all variables and methods defined in the class body are passed to a call to "type" (which is the default metaclass) as a dictionary.
As you know, dictionaries in Python have no ordering, so ordinarily it is impossible in Python2. It is possible in Python 3 because metaclasses can implement a __prepare__ method which returns the mapping object that will be used to build the class body - so instead of an ordinary dict, __prepare__ could return an OrderedDict.
However, in your case, all relevant methods are decorated with #abstractmethod - we can take advantage of that to not only annotate the methods as abstract, but also mark down the order in which they appear.
You can either wrap the abstractclass decorator, or create another decorator and use both. I'd favor a new decorator that would do both things, in order to keep linecount down.
Also, you have to choose how will you keep the order of the methods and make use of it. Ordinarily iterating on the class's attributes will just iterate over a dictionary (rather a dictionary proxy), which is unorderd- so, you have to have keep a data structure were to keep the ordered methods available, and a way to record this given order. There are are some options there - but maybe, the most direct thing is to annotate the method order in the methods themselves, and retrieve them with a call to built-in sorted with an appropriate key parameter. Other means would require eithe a class decorator or a custom metaclass to work.
So here is an example of what I wrote about:
from abc import abstractmethod, ABCMeta
class OrderedAbstractMethod(object):
def __init__(self):
self.counter = 0
def __call__(self,func):
func._method_order = self.counter
self.counter += 1
return abstractmethod(func)
ordered_abstract_method = OrderedAbstractMethod()
class Abstract(object):
__metaclass__ = ABCMeta
#ordered_abstract_method
def first(self):
pass
#ordered_abstract_method
def second(self):
pass
#ordered_abstract_method
def third(self):
pass
#ordered_abstract_method
def fourth(self):
pass
print "Unordered methods: ",[method[0] for method in Abstract.__dict__.items() if not method[0].startswith("_") ]
# here it printed out - ['second', 'third', 'fourth', 'first']
print "Ordered methods: ", sorted([method for method in Abstract.__dict__.items() if not method[0].startswith("_") ], key= lambda m: m[1]._method_order)

Dynamic sub-classing in Python

I have a number of atomic classes (Components/Mixins, not really sure what to call them) in a library I'm developing, which are meant to be subclassed by applications. This atomicity was created so that applications can only use the features that they need, and combine the components through multiple inheritance.
However, sometimes this atomicity cannot be ensured because some component may depend on another one. For example, imagine I have a component that gives a graphical representation to an object, and another component which uses this graphical representation to perform some collision checking. The first is purely atomic, however the latter requires that the current object already subclassed this graphical representation component, so that its methods are available to it. This is a problem, because we have to somehow tell the users of this library, that in order to use a certain Component, they also have to subclass this other one. We could make this collision component sub class the visual component, but if the user also subclasses this visual component, it wouldn't work because the class is not on the same level (unlike a simple diamond relationship, which is desired), and would give the cryptic meta class errors which are hard to understand for the programmer.
Therefore, I would like to know if there is any cool way, through maybe metaclass redefinition or using class decorators, to mark these unatomic components, and when they are subclassed, the additional dependency would be injected into the current object, if its not yet available. Example:
class AtomicComponent(object):
pass
#depends(AtomicComponent) # <- something like this?
class UnAtomicComponent(object):
pass
class UserClass(UnAtomicComponent): #automatically includes AtomicComponent
pass
class UserClass2(AtomicComponent, UnAtomicComponent): #also works without problem
pass
Can someone give me an hint on how I can do this? or if it is even possible...
edit:
Since it is debatable that the meta class solution is the best one, I'll leave this unaccepted for 2 days.
Other solutions might be to improve error messages, for example, doing something like UserClass2 would give an error saying that UnAtomicComponent already extends this component. This however creates the problem that it is impossible to use two UnAtomicComponents, given that they would subclass object on different levels.
"Metaclasses"
This is what they are for! At time of class creation, the class parameters run through the
metaclass code, where you can check the bases and change then, for example.
This runs without error - though it does not preserve the order of needed classes
marked with the "depends" decorator:
class AutoSubclass(type):
def __new__(metacls, name, bases, dct):
new_bases = set()
for base in bases:
if hasattr(base, "_depends"):
for dependence in base._depends:
if not dependence in bases:
new_bases.add(dependence)
bases = bases + tuple(new_bases)
return type.__new__(metacls, name, bases, dct)
__metaclass__ = AutoSubclass
def depends(*args):
def decorator(cls):
cls._depends = args
return cls
return decorator
class AtomicComponent:
pass
#depends(AtomicComponent) # <- something like this?
class UnAtomicComponent:
pass
class UserClass(UnAtomicComponent): #automatically includes AtomicComponent
pass
class UserClass2(AtomicComponent, UnAtomicComponent): #also works without problem
pass
(I removed inheritance from "object", as I declared a global __metaclass__ variable. All classs will still be new style class and have this metaclass. Inheriting from object or another class does override the global __metaclass__variable, and a class level __metclass__ will have to be declared)
-- edit --
Without metaclasses, the way to go is to have your classes to properly inherit from their dependencies. Tehy will no longer be that "atomic", but, since they could not work being that atomic, it may be no matter.
In the example bellow, classes C and D would be your User classes:
>>> class A(object): pass
...
>>> class B(A, object): pass
...
>>>
>>> class C(B): pass
...
>>> class D(B,A): pass
...
>>>

Categories

Resources