import matplotlib.pyplot as plt
import numpy as np
import plotly.graph_objects as go # run "pip install plotly==4.9.0" in your terminal to install plotly
import yfinance as yf
import numpy as np
import ast
eurusd = yf.Ticker("EURUSD=X")
usd_to_eur = 1 / (eurusd.info["ask"])
eur_to_usd = 1 * eurusd.info["ask"]
class Asset:
def __init__(self,name, ticker, amount):
self.amount = amount
self.name = name
self.ticker = ticker
self.price = yf.Ticker(self.ticker).info["regularMarketPrice"]
class Usd_asset(Asset):
def __init__(self, name, ticker, amount, buy_price):
super().__init__(name, ticker, amount)
self.buy_price = buy_price
self.buy_price_eur = [x * usd_to_eur for x in self.buy_price]
self.price_usd = yf.Ticker(self.ticker).info["regularMarketPrice"]
self.price_eur = self.price_usd * usd_to_eur
class Crypto(Asset):
def __init__(self, name, ticker, amount):
super().__init__(name, ticker, amount)
print("crypto")
class Crypto_Usd(Crypto, Usd_asset):
def __init__(self, name, ticker, amount, buy_price):
Usd_asset.__init__(self, name = name, ticker = ticker, amount = amount, buy_price = buy_price)
Crypto.__init__(self, name = name, ticker = ticker, amount = amount)
print("crypto usd")
Whenever I run it, I get the following:
Attribute Error: Type object 'Usd_asset' has no attribute '_Crypto_Usd__init'
What am I doing wrong here?
My goal is to have a class which inherits both from Crypto and from Usd_asset. which in their turn both inherit from Asset.
In Python 3.8.6 I can't reproduce the error but I get an other strange behavior:
class Asset:
def __init__(self, name):
print("init Asset")
self.name = name
class Usd_asset(Asset):
def __init__(self, name):
print("init Usd_asset")
super().__init__(name)
print("done Usd_asset")
class Crypto(Asset):
def __init__(self, name):
print("init Crypto", Crypto.__mro__)
super().__init__(name)
print("done Crypto")
class Crypto_Usd(Crypto, Usd_asset):
def __init__(self, name):
print("init Crypto_Usd")
Usd_asset.__init__(self, name = name)
Crypto.__init__(self, name = name)
print("done Crypto_Usd")
print("\nCrypto('bar')")
x = Crypto('bar')
print("\nCrypto_Usd('foo')")
a = Crypto_Usd('foo')
The output:
Crypto('bar')
init Crypto (<class '__main__.Crypto'>, <class '__main__.Asset'>, <class 'object'>)
init Asset
done Crypto
Crypto_Usd('foo')
init Crypto_Usd
init Usd_asset
init Asset
done Usd_asset
init Crypto (<class '__main__.Crypto'>, <class '__main__.Asset'>, <class 'object'>)
init Usd_asset ## <<<--- strange
init Asset
done Usd_asset
done Crypto
done Crypto_Usd
The problem is the calling of Usd_asset.__init__()
inside the Crypto.__init__()
method. The __mro__
shows that Asset
is the only super class.
With the full code I get an Exception in Crypto.__init__()
__init__() missing 1 required positional argument: 'buy_price'
It tries to call Usd_asset.__init__()
Don't use super()
in classes that are used in multiple inheritance. Or maybe never use super()
because you don't know if the class will be used in multiple inheritance.
Always write the Class.method(self, arguments)
class Usd_asset(Asset):
def __init__(self, name, ticker, amount, buy_price):
Asset.__init__(self, name, ticker, amount)
self.buy_price = buy_price
self.buy_price_eur = [x * usd_to_eur for x in self.buy_price]
self.price_usd = yf.Ticker(self.ticker).info["regularMarketPrice"]
self.price_eur = self.price_usd * usd_to_eur
class Crypto(Asset):
def __init__(self, name, ticker, amount):
Asset.__init__(self, name, ticker, amount)
print("crypto")
Edit
The reason super()
in Crypto.__init__()
chooses Usd_asset.__init__()
is because super()
or super(Crypto, self)
uses self.__class__.__mro__
to find the first parent class of Crypto
class.
In case self
is instance of Crypto
self.__class__.__mro__ (<class '__main__.Crypto'>, <class '__main__.Asset'>, <class 'object'>)
Asset
will be chosen.
In case self
is instance of Crypto_Usd
self.__class__.__mro__ (<class '__main__.Crypto_Usd'>, <class '__main__.Crypto'>, <class '__main__.Usd_asset'>, <class '__main__.Asset'>, <class 'object'>)
Usd_asset
will be chosen.
class Crypto(Asset):
def __init__(self, name):
print("init Crypto", Crypto.__mro__)
print("self.__class__.__mro__", self.__class__.__mro__)
super().__init__(name)
print("done Crypto")
The __mro__
tuple does not show the multiple inheritance and thus creates this strange behavior.
因为当您使用super()
时,您的实例是Crypto_Usd ,所以您没有按预期获得类Asset => 将调用super().__init(...)
替换为Asset.__init__(self, ...)
import matplotlib.pyplot as plt
import numpy as np
import plotly.graph_objects as go # run "pip install plotly==4.9.0" in your terminal to install plotly
import yfinance as yf
import numpy as np
import ast
eurusd = yf.Ticker("EURUSD=X")
usd_to_eur = 1 / (eurusd.info["ask"])
eur_to_usd = 1 * eurusd.info["ask"]
class Asset:
def __init__(self,name, ticker, amount):
self.amount = amount
self.name = name
self.ticker = ticker
self.price = yf.Ticker(self.ticker).info["regularMarketPrice"]
class Usd_asset(Asset):
def __init__(self, name, ticker, amount, buy_price):
super().__init__(name, ticker, amount)
self.buy_price = buy_price
self.buy_price_eur = [x * usd_to_eur for x in self.buy_price]
self.price_usd = yf.Ticker(self.ticker).info["regularMarketPrice"]
self.price_eur = self.price_usd * usd_to_eur
class Crypto(Asset):
def __init__(self, name, ticker, amount):
super().__init__(name, ticker, amount)
print("crypto")
class Crypto_Usd(Crypto, Usd_asset):
def __init__(self, name, ticker, amount, buy_price):
Usd_asset.__init__(self, name = name, ticker = ticker, amount = amount, buy_price = buy_price)
Crypto.__init__(self, name = name, ticker = ticker, amount = amount)
print("crypto usd")
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.