Python3.Descriptor.Class - python-3.x

Hello i have simply task, but i am stuck again:
How can i use variable from class into descriptor?
I have commission variable from parent class and i need use it into descriptor while calling set: self.amount = int(amount) * int(commission)
How can i do this?
Thank you!
Full code bellow:
class Value():
def __init__(self):
return
def __get__(self, obj, obj_type):
return self.amount
def __set__(self, obj, amount, commission):
self.amount = int(amount) * int(commission)
class Account:
def __init__(self, commission):
self.commission = commission
amount = Value(self.commission)
new_account = Account(0.1)
new_account.amount = 100
print(new_account.amount)

right code is below:
class Value():
def __init__(self):
return
def __get__(self, obj, obj_type):
return self.value
def __set__(self, obj, value):
self.value = value * (1 - obj.commission)
class Account:
amount = Value()
def __init__(self, commission):
self.commission = commission
new_account = Account(0.1)
new_account.amount = 100
print(new_account.amount)
The trick that, when you call __set__ on descriptor you pass obj inside, and you can call any variable or method as usual obj.xxx, that is basic i know but i am really noob with OOP.

Related

How can I access actual output instead of location index when I call methods in another method in a python class

def get_all_values(self):
values_list = [self.get_input_cable, self.get_output_cable, self.get_color, self.get_price]
return values_list
This is the output when I called out the methods into a list and printed it.
\[\<bound method Charger.get_input_cable of \<__main__.Charger object at 0x1030b4e10\>\>, \<bound method Charger.get_output_cable of \<__main__.Charger object at 0x1030b4e10\>\>, \<bound method Charger.get_color of \<__main__.Charger object at 0x1030b4e10\>\>, 600\]
I have tried the below code:
class Charger(object):
def __init__(self, input_cable, output_cable, color=None):
self.input_cable = input_cable
self.output_cable = output_cable
self.color = color
self.price = 0
def __str__(self):
return "Input: " + str(self.input_cable) + "\nOutput: " + str(self.output_cable) + "\nColor: " + str(self.color)
# Getters
def get_input_cable(self):
return self.input_cable
def get_output_cable(self):
return self.output_cable
def get_color(self):
return self.color
def get_price(self):
return self.price
# Setters
def set_input_cable(self, input_cable):
self.input_cable = input_cable
def set_output_cable(self, output_cable):
self.output_cable = output_cable
def set_color(self, color):
self.color = color
def set_price(self, price):
self.price = price
# Behaviours (Methods)
def sale(self,discount=0):
sale_price = self.price - self.price * discount/100
return sale_price
def get_all_values(self):
values_list = [self.get_input_cable, self.get_output_cable, self.get_color, self.get_price]
return values_list
C1 = Charger("C type", "B type", "Black")
C2 = Charger("USB", "C type", "White")
C1.set_price(600)
C2.set_price(1300)
print(C1.get_price())
print(C2.get_price())
print(C1.get_all_values())
If you want to access the actual output value of a method called within another method in a Python class, you can either store the output value in a variable within the method and return it, or you can directly return the output value from the method call in the return statement of the calling method.
For example, if you have a method method1 that calls another method method2, you can either do:
class MyClass:
def method1(self):
result = self.method2()
# do something with result
return result
def method2(self):
# do some computation
return output_value
or you can simply do:
class MyClass:
def method1(self):
result = self.method2()
# do something with result
return result
def method2(self):
# do some computation
return output_value
In both cases, output_value is the actual output of method2.

How could I create a docstring decorator in the presence of properties?

I have a collection of ever more specialized classes which correspond to collections of the same kind of data (temperature, density, etc) but for different drifts, for example, one subclass has dimensions (nx, ny) and a different suclass has dimensions (ncv), and I want to reflect that in the docstrings, for having a better documentation using Sphinx.
After reading many very useful threads here in Stack Overflow, I have arrived to this model:
import numpy as np
from functools import wraps
def class_decorator(cls):
import ipdb; ipdb.set_trace()
clsdict = {}
mro = cls.mro()
mro.reverse()
for tmp in mro[1:]: ##Ignore object class parent.
clsdict.update(tmp.__dict__)
for name, method in clsdict.items():
if hasattr(method, '__og_doc__'):
try:
method.__doc__ = method.__og_doc__.format(**clsdict)
except:
pass
else:
try:
method.__og_doc__ = method.__doc__
method.__doc__ = method.__doc__.format(**clsdict)
except:
pass
return cls
def mark_documentation(fn):
if not hasattr(fn, '__og_doc__'):
try:
fn.__og_doc__ = fn.__doc__
except:
pass
#wraps(fn)
def wrapped(*args, **kwargs):
return fn(*args, **kwargs)
return wrapped
def documented_property(fn):
if not hasattr(fn, '__og_doc__'):
try:
fn.__og_doc__ = fn.__doc__
except:
pass
#wraps(fn)
def wrapped(*args, **kwargs):
return fn(*args, **kwargs)
prp= property(wrapped)
prp.__og_doc__ = fn.__og_doc__
return prp
#class_decorator
class Base(object):
_GRID_DIM = 'nx, ny'
_TYPE = 'BaseData'
def __init__(self, name):
self.name = name
def shape(self):
""" This docstring contains the type '{_TYPE}' of class."""
print('Simple')
def operation(self, a, b, oper=np.sum, **kwargs):
""" Test for functions with args and kwargs in {_TYPE}"""
return oper([a,b])
#classmethod
def help(cls, var):
try:
print(get(cls, var).__doc__)
except:
print("No docstring yet.")
#class_decorator
class Advanced(Base):
_GRID_DIM = 'ncv'
_TYPE = 'AdvancedData'
def __init__(self,name):
super().__init__(name)
#property
#mark_documentation
# #documented_property
def arkansas(self):
"""({_GRID_DIM}, ns): Size of Arkansaw."""
return 'Yeah'
I am aiming to get the correctly formatted docstring when I call the help method or I use Sphinx, so that:
> adv = Advanced('ADV')
> adv.help("arkansas")
(ncv, ns): Size of Arkansaw.
> adv.help("operation")
Test for functions with args and kwargs in AdvancedData
I have managed to make it work so far, except for properties, because I assigned __og_doc__ to the function, but the property does not have that attribute. My last attempt at monkeypatching this, documented_property, fails because property is inmutable (as expected), and I cannot come up with any way to avoid this roadblock.
Is there any way around this problem?

Python: for multiple properties use one getter and setter method

I have created a class that has multiple properties. I want to use one function for the getter method and the second one for the setter method.
class person:
def __init__(self, fname, lname, city, state):
# make all attributes as private
self._fname = fname
self._lname = lname
self._city = city
self._state = state
#property # get method
def fname(self):
return self._fname
#fname.setter # set method
def fname(self,fname):
self._fname = fname
#property
def lname(self):
return self._lname
#lname.setter
def lname(self,lname):
self._lname = lname
#property
def city(self):
return self._city
#city.setter
def city(self, city):
self._city = city
#property
def state(self):
return self._state
#state.setter
def state(self, state):
self._state = state
How to use all properties for one get methods and one set method?
e.g.:
def get(self):
return self._attr
def set(self,value):
self._attr = value
class person:
def __set_name__(self, name):
self.name = name
def __get__(self, obj, type=None) -> object:
return obj.__dict__.get(self.name)
def __set__(self, obj, value) -> None:
obj.__dict__[self.name] = value
my_value = person
my_values.fname = 'Shivam'
my_values.lname = 'Gupta'
print(my_values.fname) #--> Shivam
print(my_values.lname) #--> Gupta

Implementing a python class

I am working on a personal project and I am having trouble implementing this following part.
Implementing a Menu Class.
This class will make use of MenuItem objects.
This class represents the restaurant menu which contains 4 different categories of menu item diners can order from.
This class will have a single class(or static) variable:
Menu_Item_types: a list containing 4 strings representing the 4 possible types of menu items.: Drink, appetizer, entree, dessert.
This class will use the following instance attribute:
List item
self.menuItemDrinkList: list of all drink list
self.menuItemAppetizerList: list of all appetizer list
self.menuItemEntreeList: a list of all entree list
self.menuItemDessertList: a list of all the dessert list
Below is the menuItem object
class MenuItem:
def __init__(self, name=None, types=None, price=None, description=None):
self.name = name
self.types = types
self.price = price
self.description = description
def setName(self, name):
self.name = name
def getName(self):
return self.name
def setTypes(self, types):
self.types = types
def getTypes(self):
return self.types
def setPrice(self, price):
self.price = price
def getPrice(self):
return self.price
def setDescription(self, description):
self.description = description
def getDescription(self):
return self.description
def __str__(self):
return "{} ({}): ${}, {}".format(self.name, self.types, self.price, self.description)
If I understand you correctly you are looking for setters and getters properties. Here is the way how you do it in Python.
You can learn more about properties here:
class MenuItem:
def __init__(self, name=None, types=None, price=None, description=None):
self._name = name
self._types = types
self._price = price
self._description = description
#property
def name(self):
return self._name
#name.setter
def name(self, name):
self._name = name
#property
def types(self):
return self._types
#types.setter
def types(self, types):
self._types = types
#property
def price(self):
return self._price
#price.setter
def price(self, price):
self._price = price
#property
def description(self):
return self._description
#description.setter
def description(self, description):
self._description = description
def __str__(self):
return "{} ({}): ${}, {}".format(
self._name, self._types, self._price, self._description
)
menu_item = MenuItem("pizza", "entry", 10)
print(menu_item)
menu_item.price = 20
menu_item.description = "Delicious"
print(menu_item)
output:
pizza (entry): $10, None
pizza (entry): $20, Delicious
Please notice:
In python you don't call properties with getXxx or setXxx, you just use regular names and decoreate methods with #property and #xxx.setter
You should have #property before #setter.
Setter must start with the property name
In order to escape recursion, name your internal
attributes with _ (_name). If you will not do it you will have a
"RecursionError: maximum recursion depth exceeded in comparison"
because setter will call itself in the loop.

Apply decorator to all method of sub classes for timeit

I have a method decorator looking like
def debug_run(fn):
from functools import wraps
#wraps(fn)
def wrapper(self, *args, **kw):
# log some stuff
# timeit fn
res = fn(self, *args, **kw)
return wrapper
Right now I used to use it apply on each method that I want to debug. Now i'm trying to apply to all class method using a class decorator looking like.
Rather doing
class A():
#debug_run
def f(self):
pass
I do
#decallmethods(debug_run)
class A():
def f(self):
pass
def decallmethods(decorator):
def dectheclass(cls):
for name, m in inspect.getmembers(cls, inspect.ismethod):
if name in getattr(cls, 'METHODS_TO_INSPECT', []):
setattr(cls, name, decorator(m))
return cls
return dectheclass
Trying to apply to decorator to the base class, not working as expected. no log to the console. Now i wonder if this approach is the good or I should used something else (apply the debug decorator to selected method from base class to all sub classes).
[EDIT]
Finally found why no logs were printed
Why is there a difference between inspect.ismethod and inspect.isfunction from python 2 -> 3?
Here a complete example reflecting my code
import inspect
import time
import logging as logger
from functools import wraps
logger.basicConfig(format='LOGGER - %(asctime)s %(message)s', level=logger.DEBUG)
def debug_run(fn):
#wraps(fn)
def wrapper(self, *args, **kw):
logger.debug(
"call method %s of instance %s with %r and %s "
% (fn.__name__, self, args, kw))
time1 = time.time()
res = fn(self, *args, **kw)
time2 = time.time()
logger.debug(
"%s function %0.3f ms" % (fn, (time2-time1)*1000.0))
return res
return wrapper
def decallmethods(decorator):
def dectheclass(cls):
for name, m in inspect.getmembers(
cls, predicate=lambda x: inspect.isfunction(x) or inspect.ismethod(x)):
methods_to_inspect = getattr(cls, 'METHODS_TO_INSPECT', [])
if name in methods_to_inspect:
setattr(cls, name, decorator(m))
return cls
return dectheclass
class B(object):
METHODS_TO_INSPECT = ["bfoo1", "bfoo2", "foo"]
def __str__(self):
return "%s:%s" % (repr(self), id(self))
def bfoo1(self):
pass
def bfoo2(self):
pass
def foo(self):
pass
def run(self):
print("print - Base run doing nothing")
class C(object):
pass
#decallmethods(debug_run)
class A(B, C):
METHODS_TO_INSPECT = ["bfoo1", "bfoo2", "foo", "run"]
def foo(self):
print("print - A foo")
def run(self):
self.bfoo1()
self.bfoo2()
self.foo()
a = A()
b = B()
a.run()
b.run()
In this case applying decallmethods to B, will not affect the A so i must to apply to both A and B thus to all sub classes of B.
It is possible to have such mechanism that permit to apply decallmethods to all sub classes methods ?
look at this:
How can I decorate all functions of a class without typing it over and over for each method added? Python
delnan has a good answer,
only add this rule to his answer
if name in getattr(cls, 'METHODS_TO_INSPECT', []):

Resources