Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dataclass Class of 'Dataclass Class'es Python 3.8 #1

Open
mrkgoh opened this issue Dec 6, 2021 · 0 comments
Open

Dataclass Class of 'Dataclass Class'es Python 3.8 #1

mrkgoh opened this issue Dec 6, 2021 · 0 comments

Comments

@mrkgoh
Copy link

mrkgoh commented Dec 6, 2021

@egges , I follow your video avidly. Thanks ! Have a design related question :

I have a dataclass of a single class object 'AStock' as such:

@dataclass
class AStock:
    
    code_: Union[str, int]
    force_update_: bool = False
    ticker_: str = field(init=False)
    symbol_: str = field(init=False)
    name_: str = field(init=False)
    sector_: str = field(init=False)
    subsector_: str = field(init=False)
    
    @exception(logger)
    def __post_init__(self) -> None:
        try:
            self.code_ = str(self.code_).zfill(4)
            self.ticker_ = indexer(code=self.code_, arg='ticker')
            self.symbol_ = indexer(code=self.code_, arg='symbol')
            self.name_ = indexer(code=self.code_, arg='full_name')
            self.sector_ = indexer(code=self.code_, arg='sector')
            self.subsector_ = indexer(code=self.code_, arg='subsector')

        except NoStockFound:
            raise
        except Exception as e:
            raise StockException(stock=self) from e

What I want to achieve is to create a class object that would initialize a single stock object or a collection of stock objects. So I did a 'Stocks' and a 'Stock' object.

'Stocks' here initializes a group of 'AStock' objects.

@dataclass
class Stocks:
    
    code_: List[str]
    force_update_: bool = False
    ticker_: str = field(init=False)
    symbol_: str = field(init=False)
    name_: str = field(init=False)
    sector_: str = field(init=False)
    subsector_: str = field(init=False)
    
    @exception(logger)
    def __post_init__(self) -> None:
        self.ticker_ = [indexer(code, arg='ticker') for code in self.code_]
        self.symbol_ = [indexer(code, arg='symbol') for code in self.code_]
        self.name_ = [indexer(code, arg='full_name') for code in self.code_]
        self.sector_ = [indexer(code, arg='sector') for code in self.code_]
        self.subsector_ = [indexer(code, arg='subsector') for code in self.code_]
    
    def __repr__(self) -> str:
        return ', '.join([f'{i[0]}:{i[1]}' for i in list(zip(self.code_, self.ticker_))])
    
    def __str__(self) -> str:
        return ', '.join([f'{i[0]}:{i[1]}' for i in list(zip(self.code_, self.ticker_))])

and this 'Stock' object here is to handle the creation of 'AStock' or 'Stocks' object.

@dataclass
class Stock:
    code: Union[str, int, List[str]]
    force_update: bool = False
    
    @exception(logger)
    def __new__(cls, code, force_update: bool = False):
        if type(code) in [str, int]:
            return AStock(code, force_update)
        
        elif type(code) in [list]:
            return Stocks(code, force_update)
        
        else:
            raise ValueError('Not a valid stock code')

So for example:
If Stock(['1203', '1232']) will create Stocks object and Stock('1203') will create a AStock object. Just by providing arguments as a List or String it could detect whether to create AStock for single stock or Stocks for multiple stocks.

However, this is pretty 'hacky' way of using __new__ to return an either AStock object or Stocks object. Is there a more elegant way of doing this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant