Python OOP用一种方法处理两个对象

时间:2019-07-06 15:38:17

标签: python oop

我是Python的新手,试图了解OOP。在我的程序中,我希望用户能够买卖股票,但是我正在努力实现此功能。对不起,如果问题不大。

用户类及其一个对象

class User:
    def __init__(self, name, budget=None, stocks=None):
        self.name = name
        self.budget = budget or 1000 
        self.stocks = stocks or 0

    def sell_stock(self):
        if self.stocks != 0:
            self.stocks -= 1

    def buy_stock(self):
        self.stocks += 1


u1 = User("Karin", stocks=9)

股票类别及其一个对象

class Stock:
    def __init__(self, price, name, availability=None):
        self.price = price
        self.name = name
        self.availability = availability or 1


s1 = Stock("200", "Netflix")

我想编写一个名为buy_stock()的方法,该方法将执行以下操作:

  • u1.budget-s1.price
  • u1.stocks + = 1
  • s1.availability-= 1
  • 将显示价格和用户拥有的股票名称 已购买,因此我将看到一条消息“ f“ {Karin}购买了{Netflix} 股票的价格为{200}美元。”

6 个答案:

答案 0 :(得分:2)

class Stock:
    def __init__(self, price, name, availability=1):
        self.price = price
        self.name = name
        self.availability = availability

class User:
    def __init__(self, name, budget=1000,):
        self.name = name
        self.budget = budget 
        self.stocks = []

    def sell_stock(self, stock):
        try:
            self.stocks.remove(stock)
            stock.availability += 1
            self.budget += stock.price
            print('{} has sold {} stock for {} dollars'.format(self.name, stock.name, stock.price))

        except:
          pass

    def buy_stock(self, stock):
        if self.budget - stock.price >= 0 and stock.availability >= 1:
            self.stocks.append(stock)
            stock.availability -= 1
            self.budget -= stock.price
            print('{} has bought {} stock for {} dollars'.format(self.name, stock.name, stock.price))

s1 = Stock(200, "Netflix")
s2 = Stock(300, "SomeStock", availability=2)

u1 = User("Karin", budget=10000)
u1.buy_stock(s2)
u1.sell_stock(s2)

u2 = User("Sam")
u2.buy_stock(s2)
u2.buy_stock(s1) 

输出:

Karin has bought SomeStock stock for 300 dollars
Karin has sold SomeStock stock for 300 dollars
Sam has bought SomeStock stock for 300 dollars
Sam has bought Netflix stock for 200 dollars

购买物品时,必须确保该物品可用且有预算。我从构造函数中删除了股票参数以避免重复,并且只为逻辑buy_stock提供一个来源。最后一点:您不需要or键控,因为您可以在构造函数中设置默认值。

答案 1 :(得分:1)

要想在更现实的情况下考虑它,您将拥有一个Marketplace对象,该对象包含其他用户可以从中购买股票的所有股票。
 这样,将来的开发将相当容易可读可扩展

Marketplace可以是一个单独的类,可以容纳其他库存对象的字典(如下面的示例所示),也可以是与数据库连接的类(如mongodb)。
选择哪一个取决于项目。

在此示例中,词典是使您前进的绝佳解决方案:

class User:
    def __init__(self, name, budget=None, stocks=None):
        self.name = name
        self.budget = budget or 1000
        self.stocks = stocks or 0

    def __repr__(self):
        # returns a represantion of the object
        # so it's more informative of the state
        # of this object
        return "{} balance: {}".format(
            self.name,
            self.budget
        )

    def sells(self, stock_name, amount):
        # Increase my budget by the amount of stocks I'm selling 
        # multiplied by its price.
        self.budget += marketplace[stock_name].price * amount

        # Send the stocks back into the market and remove them
        # from my ownership
        marketplace[stock_name].availability += amount
        self.stocks -= amount


    def buys(self, stock, amount):
        # Lower my budget by the stock price 
        # multiplied by the amount of stock I'm buying

        marketplace[stock].availability -= amount
        self.budget -= marketplace[stock].price * amount

        # Print out the transaction
        print("{} has bought {} stock for {} dollars".format(
            self.name,
            stock,
            marketplace[stock].price * amount
        ))


class Stock:
    def __init__(self, price, name, availability=None):
        self.price = price
        self.name = name
        self.availability = availability or 1

# In production like environmnet, you would not do this but would keep in
# mongodb or some other sql/nosql database
# For this example, a kind of javascript dict logic would be alright to use
marketplace = {
    "Netflix": Stock(200, "Netflix", 100)
}

u1 = User("Karin", budget=1000, stocks=0)

u1.buys("Netflix", 10)
u1.sells("Netflix", 5)

答案 2 :(得分:1)

欢迎来到OOP的世界:)

您要尝试做的非常简单。由于您要尝试同时使用两个类,因此这表示应将其中一个类用作函数中的参数。即

class Stock:
     # .... basic init function

     # we need a function to return the value
     # of this stock, and maybe take an argument
     # for how many shares we want to value
     # so let’s write a function to do that for us

     def get_value(self, number_of_shares=1):
         return (self.value * number_of_shares)

class User:
     #.... basic init function

     def buy_stock(self, stock, amount=1):
          total_value = stock.get_value(amount)
          self.budget = self.budget - total_value
          self.stocks = self.stocks + amount

          #display what happened
          print(“{} bought {} shares of {} for {}”.format(self.name, amount, stock.name, total_value))

然后您可以在实践中写

输入:

# assuming Andrew is a user
# and my_stock is a stock worth $20 a share
Andrew.buy_stock(my_stock, 10)

输出:

Andrew bought 10 shares of my_stock for $200

但基本上,问题的答案是传递一个您希望成为您要使用的类的参数。因此,您既可以操纵调用该方法的User对象,也可以操纵传递到该方法中的库存对象。

答案 3 :(得分:1)

我认为应该这样做。另外,将股票价格的数据类型从字符串更改为整数(或之后进行类型转换)

class User:
    def __init__(self, name, budget=None, stocks=None):
        self.name = name
        self.budget = budget or 1000 
        self.stocks = stocks or 0

    def sell_stock(self):
        if self.stocks != 0:
            self.stocks -= 1

    def buy_stock(self, stock):
        self.budget - stock.price
        stock.availability -= 1
        self.stocks += 1
        print("{} has bought {} stock for {} dollars".format(self.name,stock.name,stock.price))

class Stock:
    def __init__(self, price, name, availability=None):
        self.price = price
        self.name = name
        self.availability = availability or 1


s1 = Stock(200, "Netflix")

u1 = User("Karin", stocks=9)

u1.buy_stock(s1)

答案 4 :(得分:1)

您需要两种类型的对象:backup-inhibitedPortfolio
Stock可以有多个User,并且在示例中仅由其名称表示。

对于更复杂的模型,您也将Portfolio建模为对象;您还需要处理库存价格,佣金和其他成本的变化。

这是一个简化的示例,演示了对象之间的交互方式:

Transactions

输出:

class Stock:

    def __init__(self, ticker, price):
        assert price > 0
        self.ticker = ticker
        self.price = price

    def __hash__(self):
        return hash(self.ticker)

    def __str__(self):
        return self.ticker + ', $' + str(self.price) + ':'


class Portfolio:

    def __init__(self, owner):
        self.owner = owner
        self.cash = 0
        self.stocks = {}   # a mapping of Stock --> quantity

    def buy(self, stock, quantity):
        if self.cash < stock.price * quantity:
            print('Not enough cash to purchase ', quantity, stock)
        else:
            self.cash -= stock.price * quantity
            try:
                self.stocks[stock] += quantity
            except KeyError:
                self.stocks[stock] = quantity

    def sell(self, stock, quantity):
        assert quantity > 0
        try:
            if self.stocks[stock] < quantity:
                print('Not enough', stock.ticker, 'inventory to sell', str(quantity), stock)
                return
            self.stocks[stock] -= quantity * stock.price
            self.cash += quantity * stock.price
        except KeyError:
            print('No', stock.ticker, 'inventory to sell')

    def __str__(self):
        res = [self.owner, "'s Portfolio:\n"]
        for stock, quantity in self.stocks.items():
            res += [str(stock), ' ', str(quantity), ' -> ', '$', str(quantity*stock.price), '\n']
        res += ['cash: ', '$', str(self.cash), '\n']
        return ''.join(res)

goog = Stock('GOOG', 325)
alibaba = Stock('ALI', 12)
apple = Stock('AAPL', 42)

pfl = Portfolio('Karin')
pfl.cash = 10000

pfl.buy(goog, 10)
pfl.buy(alibaba, 100)
pfl.sell(apple, 100)
pfl.buy(apple, 10000)
pfl.sell(goog, 10000)

print()
print(pfl)

答案 5 :(得分:1)

可能是这样的事情(我并没有真正弄混“ User”类中的“ stocks”实例变量。我可能会抛弃它,而是维护一个Stock对象列表(您的库存数量就是该列表的长度)):

class User:

    def __init__(self, name, budget=1000, stocks=0):
        self.name = name
        self.budget = budget
        self.stocks = stocks

    def sell_stock(self):
        if self.stocks:
            self.stocks -= 1

    def buy_stock(self, stock, quantity=1):
        try:
            price = stock.request(quantity)
        except RuntimeError as error:
            raise error
        else:
            self.budget -= price
            self.stocks += quantity
            print(f"{self.name} bought ${price} worth of {stock.name} stocks")

class Stock:

    def __init__(self, name, price, quantity_available=1):
        self.name = name
        self.price = price
        self.quantity_available = quantity_available

    def isAvailable(self):
        return self.quantity_available > 0

    def request(self, quantity_requested):
        if not self.isAvailable():
            raise RuntimeError(f"No more {self.name} stocks available")
        elif self.quantity_available < quantity_requested:
            raise RuntimeError(f"Requested too many {self.name} stocks")
        else:
            self.quantity_available -= quantity_requested
            return self.price * quantity_requested

def main():

    user = User("Karin")

    stock = Stock("Netflix", 200, quantity_available=6)

    user.buy_stock(stock, quantity=3)
    user.buy_stock(stock, quantity=2)
    user.buy_stock(stock, quantity=1)

    user.buy_stock(stock, quantity=1)

    return 0


if __name__ == "__main__":
    import sys
    sys.exit(main())

输出:

Karin bought $600 worth of Netflix stocks
Karin bought $400 worth of Netflix stocks
Karin bought $200 worth of Netflix stocks
RuntimeError: No more Netflix stocks available