I have this two classes:
class Extraction:
def extract(self):
df_final = pd.DataFrame()
for index in range(0, jsonPartidas.shape[0]):
jsonPartidasIndex = json.loads(list(jsonPartidas['data'])[index])
df_ratios = self.func(jsonPartidasIndex)
cif, denominacion = cif_denominacion(jsonPartidasIndex)
df_ratios['cif'] = cif
df_ratios['denominacion'] = denominacion
df_final = df_final.append(df_ratios)
ratios = df_final.drop_duplicates()
class Ratios(Extraction):
# func = Ratios.find_ratio
def __init__ (self, partidasRatios):
self.codigos = list(partidasRatios.values())
self.nombreColumnas = list(partidasRatios.keys())
self.func = Ratios.find_ratio
def find_ratio(self,jsonPartidasIndex):
self.listaRatios = list(findkeys(jsonPartidasIndex,'listaRatios'))
self.annosBalance = list(findkeys(jsonPartidasIndex,'annoBalance'))
df_ratios = self.parseRatios()
return df_ratios
def parseRatios(self):
self.dic_codes = {}
self.dic_codes['anno'] = self.annosBalance
self.getRatios()
df_ratios = pd.DataFrame(self.dic_codes)
return df_ratios
def getRatios(self):
for num, self.cod in enumerate(self.codigos):
self.ratios = []
self.findRatios()
self.dic_codes[self.nombreColumnas[num]] = self.ratios
def findRatios(self):
for ind in range(0,len(self.listaRatios)):
ratio = self.listaRatios[ind]
self.getValueFromRatio(ratio, ind)
def getValueFromRatio(self,ratio,ind):
for index in range(0,len(ratio)):
dictio = list(findkeys(ratio[index],'valor'))
if self.cod in dictio:
valor = [ x for x in dictio if isinstance(x, float) or isinstance(x,int)]
if valor:
self.ratios.append(valor[0])
else:
self.ratios.append(None)
break
elif index == len(ratio)-1 and len(self.ratios) < ind 1:
self.ratios.append(None)
I have a few classes with the method extract() that is why I create a class call Extraction that is being inherted by the other classes one of them is Ratio. I want to assign the a method that is created inside of my Ratio class call find_ratio, to the self.func so when I execute Ratios(partidasRatios).extract() (as you can see I do not want to pass any parameters to the extract method), it will run the code. I tried a lot of things and I think i got closer with the example above but I still get this error:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
C:\Users\ALVARO~1\AppData\Local\Temp/ipykernel_11044/3560029455.py in <module>
----> 1 ratios = Ratios(partidasRatios).extract()
C:\Users\ALVARO~1\AppData\Local\Temp/ipykernel_11044/1705348355.py in extract(self)
6 for index in range(0, jsonPartidas.shape[0]):
7 jsonPartidasIndex = json.loads(list(jsonPartidas['data'])[index])
----> 8 df_ratios = self.func(jsonPartidasIndex)
9 cif, denominacion = cif_denominacion(jsonPartidasIndex)
10 df_ratios['cif'] = cif
TypeError: find_ratio() missing 1 required positional argument: 'jsonPartidasIndex'
If you zoom in you can see that jsonPartidasIndex it is actually pass.
CodePudding user response:
Your find_ratio
is not a class method, but a "regular" instance method.
So your assignment in __init__
should look like this imho:
self.func = self.find_ratio
No offense, but you could improve the overall design though.
You can make the whole base class abstract or at least raise an error in base class and provide implementation in the class which inherits from Extraction
.
class Extraction:
def extract(self):
func_arg = ... # get the argument any way you want
self.func(func_arg)
def func(self, *args, **kwargs):
raise NotImplementedError("Overload this with specific implementation!")
class Ratios(Extraction):
def func(self, func_argument):
... # your specific implementation goes here
ratios = Ratios()
ratios.extract()
Some off-topic tips:
- python likes snake case, be consistent with it
- use English in your code (if you ever have to share it to non-Spanish (that's my guess what it is, sorry if it's Portuguese) speakers it will be easier to understand and all external libraries use English too, so you end up with mix of your language and English, which doesn't look good and is harder to analyze
- use type hints, they really help
- don't use abbreviations