Use model method in class and override that method - python-3.x

I have a method called complete in my model, how can i use that in my class view, in my model method there is one parameter called person which is being passed i do not want my
overriden method to use that parameter how can i acheive that.
class Mymodel(models.Model):
is_done = model.BooleanField()
def complete(self, person):
self.is_done = True
self.save(update_fields=['is_done'])
self.done_by.add(person)
class MyView(SomeView):
def complete_record(self):
return Mymodel.complete(here it expects two arguments i need only self)
and i want to get rid of self.done_by.add(person) in model's complete
method

The complete() method can be called for a single model instance (a single object of the queryset).
In the View, maybe you want to do this if you have a id param in url:
instance = Mymodel.objects.get(pk=self.kwargs['id'])
instance.complete()
or the scenario can be this if you are using DetailView:
self.get_object().complete()
-- EDIT --
If you want to set is_done = True without add person and
if you can't edit model class, you can put the logic in the view:
class MyView(SomeView):
def complete_record(self):
record = Mymodel.objects.get(pk=id)
record.is_done = True
record.save()
return record

Related

Accessing variables from a method in class A and using it in Class B in python3.5

I have a BaseClass and two classes (Volume and testing) which inherits from the BaseClass. The class "Volume" use a method "driving_style" from another python module. I am trying to write another method "test_Score" which wants to access variables computed in the method "driving_style" which I want to use to compute further. These results will be accessed to the class "testing" as shown.
from training import Accuracy
import ComputeData
import model
class BaseClass(object):
def __init__(self, connections):
self.Type = 'Stock'
self.A = connections.A
self.log = self.B.log
def getIDs(self, assets):
ids = pandas.Series(assets.ids, index=assets.B)
return ids
class Volume(BaseClass):
def __init__(self, connections):
BaseClass.__init__(self, connections)
self.daystrade = 30
self.high_low = True
def learning(self, data, rootClass):
params.daystrade = self.daystrade
params.high_low = self.high_low
style = Accuracy.driving_style()
return self.Object(data.universe, style)
class testing(BaseClass):
def __init__(self, connections):
BaseClass.__init__(self, connections)
def learning(self, data, rootClass):
test_score = Accuracy.test_score()
return self.Object(data.universe, test_score)
def driving_style(date, modelDays, params):
daystrade = params.daystrade
high_low = params.high_low
DriveDays = model.DateRange(date, params.daystrade)
StopBy = ComputeData.instability(DriveDays)
if high_low:
style = ma.average(StopBy)
else:
style = ma.mean(StopBy)
return style
def test_score(date, modelDays, params):
"want to access the following from the method driving_style:"
DriveDays =
StopBy =
return test_score ("which i compute using values DriveDays and StopBy and use test_score in the method learning inside
the 'class - testing' which inherits some params from the BaseClass")
You can't use locals from a call to a function that was made elsewhere and has already returned.
A bad solution is to store them as globals that you can read from later (but that get replaced on every new call). A better solution might to return the relevant info to the caller along with the existing return values (return style, DriveDays, StopBy) and somehow get it to where it needs to go. If necessary, you could wrap the function into a class and store the computed values as attributes on an instance of the class, while keeping the return type the same.
But the best solution is probably to refactor, so the stuff you want is computed by dedicated methods that you can call directly from test_score and driving_style independently, without duplicating code or creating complicated state dependencies.
In short, basically any time you think you need to access locals from another function, you're almost certainly experiencing an XY problem.

Is a python `abstract property` that returns an abstract class an example of the Factory Pattern

I need to document my design, in particular, the design patterns used, and would like to use the standard terminology.
From Refactoring Guru, "Factory Method defines a method, which should be used for creating objects instead of direct constructor call. Subclasses can override this method to change the class of objects that will be created".
I have a CraneInterface class with an abstract method, and the signature of this method enforces that its return type is an implementation of an AxisInterface. Essentially, subclasses of CraneInterface "override this method to change the class of objects that will be created". The only diference with my version is that it does not necessarily "create" a new instance, it could also return one that already exists. Is this still the Factory Pattern? And if not, does this design pattern have a common name?
i.e: A traditional factory looks like this:
class IAnimal(ABC):
#abstractmethod
def speak(self):
pass
class Dog(IAnimal):
#overide
def speak(self):
print('Woof')
class Cat(IAnimal):
#overide
def speak(self):
print('Meow')
class AnimalFactory(ABC):
#abstractmethod
def make_animal(self) -> IAnimal:
pass
class CatFactory(AnimalFactory):
#overide
def make_animal(self) -> IAnimal:
return Cat()
class DogFactory(AnimalFactory):
#overide
def make_animal(self) -> IAnimal:
return Dog()
My code looks more like this:
class AnimalFactory2(ABC):
#property
#abstractmethod
def animal(self) -> IAnimal:
pass
class CatFactory2(AnimalFactory2):
def __init__(self):
self.__cat = Cat()
#overide
#property
def animal(self) -> IAnimal:
return self.__cat
class DogFactory2(AnimalFactory2):
def __init__(self):
self.__dog = Dog()
#overide
#property
def animal(self) -> IAnimal:
return self.__dog
Does the second example use the Factory Pattern? Does it have a different name or even have a name at all? The main difference is that it does not create a new instance each time it is called.
Extra info:
In my actual code, I have a 3 axis CraneInterface class that has abstract methods for all the ways you can interact with a crane. It is implemented by a CraneSimulator and a CraneOpcuaClient that actually talks to a real crane. The original design of the simulator implemented the abstract method inside the CraneSimulator class, however, this had lots of duplicated code, as every function of the crane was repeated for each of the 3 axes. To solve this, I created an AxisSimulation class which had methods to interact with it, and then there are 3 instantiations inside the CraneSimulator, and the implementations of the CraneInterface abstract methods simply forward the request to one of the 3 axis objects.
The problem was that the CraneInterface also needed the ability to notify "observers" whenever the state of the crane changed, for example, a position or temperature change. I.e the CraneInterface needed to have a function add_on_x_position_changed_callback(self, callback: Callable[[Position],None]). To do this, the CraneInterface had properties with custom setters that notified a list of observers whenever the value was set. By putting the AxisSimulation inside the CraneSimulator the properties had moved out of the CraneInterface, and the add_on_changed_callback methods of the CraneInterface would no longer work.
So to solve this, the CraneInterface had an abstract property to return an abstract AxisInterface class (like the AnimalFactory2 example). The AxisInterface then had the observable properties with a custom setter (and methods to add observers), so that users of the CraneInterface can add observers to the data.
I know that the "observable" part is an example of the Observer pattern, but is the deferring of the type of Axis implementation returned, an example of the Factory Pattern?
Thanks.

Preventing a particular attribute's inheritance in subclass?

If I have the following :
class A:
attrs = [...]
A_attr = [...]
class B(A):
B_attr = [...]
Is there a way to prevent my B subclass from inheriting the A_attr from the A class?
Or would this be considered a bad design and I should better subclass both A and B from a third C class containing all the attrs attributes and add the particular attribute to each subclass like this?
class C:
attrs = [...]
class A(C):
A_attr = [...]
class B(C):
B_attr = [...]
Better idea is to dump the common functionality in a class.
class Commmon:
attrs = [...]
Extend this class who want this extra functonality.
class A(Common):
# only one attribute added in this class
A_attr = [...]
classB(Common):
attrs_B = [...]
Extend class A when that extra attribute is needed in the class, this will bring all those other attributes.
class C(A):
attrs_C = [...]
What this will allow is wherever you want an object of type Common you can provide instance of B as well as C. And wherever you want instance of class A you can provide instance of C. If you add specific instance in each of your subclasses you will not be able to do so.
From Comment
So according to you I should use the second solution I exposed in my question.
No.
Instead of adding the attribute in each subclass, my advice is to add the attribute in a separate class and let your new classes inherit this intermediate class. So you do not have to add the specific attribute in each one of those subclass.
Example is already provided above. Lets see what is the benefit of doing this, as opposed to your suggestion. Take the following function
def foo(obj):
# check to make sure object has the specific attribute
if (isinstance(obj, A)):
pass; #do something
else:
raise TypeError("Object is not an instance of A")
But if we add the specific attribute in each class, the method will need to be changed to something like this:
def foo(obj):
# check to make sure object has the those type which has that specific attribute
if( isinstance(obj, class1) or (isinstance(obj, class2) or ...):
pass; #do something
else:
raise TypeError("Object does not have specific attribute")
Of course, you can perform a check using something like this:
def foo(obj):
# check to make sure obj has attribute
if hasattr(obj, 'property')
pass; # do something
else:
raise TypeError("Object does not have necessary attribute")
Using correct inheritance relationship (as shown in 1st example) will also help your IDE (if you are using one) in inferring types, because IDE can determine which type of object it expects. You can even augment the function with type information like this:
def foo(obj : A):
pass; #do something
That A after colon is a hint to the IDE that function expects an object of type or subtype of A.

Dynamically assigning sub class dependent decorators

I have a class that has a basic method, and subclasses that have the same base functionality, but additional behaviour, which can be implemented with decorators.
class cls_with_basic_method:
#if...exec("#decoratorA")
#if...exec("#decoratorB")
#...
def basic_method(arg):
#...
return arg
class cls_with_basic_method_and_decoratorA(class_with_basic_method):
#...
class cls_with_basic_method_and_decoratorB(class_with_basic_method):
#...
#...
It seems the quickest solution would be if I were able to execute the particular decorator as the subclass method is called, but can't think of a way of expressing it in python. Can this easily be done?
A decorated function or method is usually a different object than the function or method it decorates [*] - so, you can just wrap the original class' method in an explict way. This is rather straightforawrd, and rather boring - but it will work if you need to decorate just a few methods of the sub-classes:
class cls_with_basic_method:
def basic_method(arg):
#...
return arg
class cls_with_basic_method_and_decoratorA(class_with_basic_method):
basic_method = decoratorA(cls_with_basic_method.basic_method)
class cls_with_basic_method_and_decoratorB(class_with_basic_method):
basic_method = decoratorB(cls_with_basic_method.basic_method)
The only special thing done there is use the decorators with the syntax of regular function calls instead of usign the "#..." syntax - this way they can be used inside the expressions.
This method is further boring due to you have to hardcode the superclass name within the class body at each decoration, since you can't use super from the class body, just from inside methods.
[*] Although some decorators just add metadata to the callable object they decorate and return the object itself - this approach won't work for such decorators, as they will affect the method in the superclass as well.
Now, taking your problem further - what you want is just to wrap arbitrary methods on the superclass when they are called on the subclasses. That can be done more or less automatically if you override the class__getattribute__ - you then could create a class hierarchy with an special "decorator" attribute that would be called for each method call - more or less like this:
class cls_with_basic_method:
_auto_decorate = set(("basic_method", ...))
_decorator = lambda x: x # NOP decorator
def basic_method(arg):
#...
return arg
def __getattribute__(self, attrname):
attr = object.__getattribute__(self, attr)
# shortcircuit non-method retrievelas as fast as possible:
if not attrname in __class__._auto_decorate not callable(attr):
return attr
return self.__class__._decorator(attr)
class cls_with_basic_method_and_decoratorA(class_with_basic_method):
_decorator = decoratorA
class cls_with_basic_method_and_decoratorB(class_with_basic_method):
_decorator = decoratorB
Of course, if you need different decorators for different methods, just change the code in __getattribute__ accordingly - the easiest way would be to make the _decorator attribute be a dictionary instead of pointing to a simple function.
(on a side note: the __class__ magic variable, when used inside a method, is a Python 3 thing: it automatically contains a reference to the class it is defined in (in this case, cls_with_basic_method).
This approach will redecorate the method on each call - it is not as much overhead as it seems to be - Python's default method retrieval mechanism itself is similarly complicated - but if you prefer to decorate the methods at class creation instead, tehn you can use a similar mechanism in a metaclass instead of relying on __getattribute__.
from itertools import chain
class AutoDecorate(type):
def __new__(metacls, name, bases, dct):
if "_decorator" not in dct:
dct["_decorator"] = lambda x: x # NOP decorator
all_bases = list(chain(base.__mro__ for base in bases))
for base in all_bases:
if not "_auto_decorate" in base.__dict__:
continue
for method_name in base.auto_decorate:
if method_name not in dct:
dct[method_name] = dct["_decorator"](getattr(base, method_name))
return super().__new__(name, bases, dct)
class cls_with_basic_method(metaclass=AutoDecorate):
_auto_decorate = set(("basic_method", ...))
def basic_method(arg):
#...
return arg
class cls_with_basic_method_and_decoratorA(class_with_basic_method):
_decorator = decoratorA
class cls_with_basic_method_and_decoratorB(class_with_basic_method):
_decorator = decoratorB
This is actually simpler than it might look: Upon creating a new class on the hierarchy, it just searches all superclasses for those which have the _auto_decorate attribute - and then it fetches the methods in that list, and decorate them with the decorator in the _decorator attribute of the class being created.
From what you are asking, I'd say you are dealing with a project where you need an "aspect oriented programing" approach. There are several Python libraries that can provide that functionality - maybe you should take a look at that. If you think so, search for modules that can provide appropriate Python aspect oriented capabilities and use those.

How do I call outside function from class in python

How do i call an outside function from this class ?
def test(t):
return t
class class_test():
def test_def(q):
test_msg = test('Hi')
print (test_msg)
To call the class method, you can create an instance of the class and then call an attribute of that instance (the test_def method).
def test(t):
return t
class ClassTest(object):
def test_def(self):
msg = test('Hi')
print(msg)
# Creates new instance.
my_new_instance = ClassTest()
# Calls its attribute.
my_new_instance.test_def()
Alternatively you can call it this way:
ClassTest().test_def()
Sidenote: I made a few changes to your code. self should be used as first argument of class methods when you define them. object should be used in a similar manner.

Resources