在Python中如何从外部单独的函数中访问类对象?

huangapple go评论74阅读模式
英文:

How to access a class object from an outside separate function in Python?

问题

class Category:

    def __init__(self, name):
        self.ledger = []
        self.total = 0
        self.name = name
        self.totalwithdrawals = 0
        pass

    def __repr__(self):
        spaces = " "
        astfull = "*" * 23  # max 23 characters
        ast = "*"
        midpos = round((30 - len(self.name)) / 2)  # finding the middle position to add the object name
        title = astfull[:midpos] + self.name + ast * (30 - (midpos + len(self.name)))  # print object name in the middle of a bunch of asterisks
        c = ""
        for i in range(0, len(self.ledger), 2):  # look into the ledger list for the amount and descriptions of deposits and withdrawals and create a report
            a_uncomp = str(self.ledger[i])
            b_uncomp = str(self.ledger[i + 1])
            a_pos = a_uncomp.find(":")
            b_pos = b_uncomp.find(":")
            a = a_uncomp[a_pos + 2:(a_pos + 10)]
            b = b_uncomp[b_pos + 2:(b_pos + 26)]
            spacesf = spaces * (30 - (len(a) + len(b)))
            c += b + spacesf + a + "\n"
        totalf = "Total: " + str(self.total)
        return title + "\n" + c + totalf

    def deposit(self, amount, description=False):  # deposit method with an optional description
        self.ledger.append("amount: " + str(amount))
        self.total += amount

        if description:
            self.ledger.append("description: " + description)
        else:
            self.ledger.append("description: ")

    def withdraw(self, amount, description=False):  # withdraw method with an optional description
        self.ledger.append("amount: " + str(-abs(amount))
                          )
        if description:
            self.ledger.append("description: " + description)
        else:
            self.ledger.append("description: ")

        if (self.total + -abs(amount)) < 0:  # return false if not enough money to withdraw the specified amount
            return False
        else:  # if enough money, rest amount from the total variable for the specific object (deposits + withdrawals).
            self.total += -abs(amount)
            self.totalwithdrawals += -abs(amount)  # separate variable storing ONLY withdrawals
            return True

# adding three categories for testing
food = Category("food")
clothing = Category("clothing")
entertainment = Category("entertainment")

# doing a bunch of random deposits and withdrawals for testing
food.deposit(1000, "initial deposit")
food.withdraw(254, "supermarket")
clothing.deposit(1000, "initial deposit")
clothing.withdraw(634.23, "prada and channel")
entertainment.deposit(536, "initial deposit")
entertainment.withdraw(152, "trip to bcn")

def create_spend_chart(categories):
    print(food.totalwithdrawals)
    print(clothing.totalwithdrawals)
    print(entertainment.totalwithdrawals)
    # These three blocks of print are what I want to get
    for i in categories:
        i = Category(i)
        print(i.totalwithdrawals)
        # but when I loop through a list with the same names as the categories, all I get is a bunch of 0s.
英文:
class Category:
def __init__(self, name):
self.ledger = []
self.total = 0
self.name = name
self.totalwithdrawals = 0
pass
def __repr__(self):
spaces = &quot; &quot;
astfull = &quot;*&quot; * 23 #max 23 characters
ast = &quot;*&quot;
midpos = round((30-len(self.name))/2) #finding the middle position to add the object name 
title = astfull[:midpos] + self.name + ast*(30-(midpos+len(self.name))) #print object name in middle of bunch of asterisks
c = &quot;&quot;
for i in range(0, len(self.ledger), 2): #look into ledger list for amount and descriptions of deposits and withdrawals and create a report
a_uncomp = str(self.ledger[i])
b_uncomp = str(self.ledger[i+1])
a_pos = a_uncomp.find(&quot;:&quot;)
b_pos = b_uncomp.find(&quot;:&quot;)
a = a_uncomp[a_pos + 2:(a_pos + 10)]
b = b_uncomp[b_pos + 2:(b_pos + 26)]
spacesf = spaces * (30 - (len(a) + len(b)))
c +=  b + spacesf + a + &quot;\n&quot;
totalf = &quot;Total: &quot; + str(self.total)
return title + &quot;\n&quot; + c + totalf
def deposit(self, amount, description = False): #deposit method with optional description
self.ledger.append(&quot;amount: &quot; + str(amount))
self.total += amount
if description:
self.ledger.append(&quot;description: &quot; + description)
else:
self.ledger.append(&quot;description: &quot;)
def withdraw (self, amount, description = False): #withdraw method with optional description
self.ledger.append(&quot;amount: &quot; + str(-abs(amount))) 
if description:
self.ledger.append(&quot;description: &quot; + description)
else:
self.ledger.append(&quot;description: &quot;)
if (self.total + -abs(amount)) &lt; 0: #return false if not enough money to withdraw specified amount
return False
else: #if enough money, rest amount from total variable for the specific object (deposits + withdrawals). 
self.total += -abs(amount)
self.totalwithdrawals += -abs(amount) #separate variable storing ONLY withdrawals
return True
#adding three categories for testing
food = Category(&quot;food&quot;)
clothing = Category(&quot;clothing&quot;)
entretainment = Category(&quot;entretainment&quot;)
#doing bunch of random deposits and withdraws for testing
food.deposit(1000, &quot;initial deposit&quot;)
food.withdraw(254, &quot;supermarket&quot;)
clothing.deposit(1000, &quot;initial deposit&quot;)
clothing.withdraw(634.23, &quot;prada and channel&quot;)
entretainment.deposit(536, &quot;initial deposit&quot;)
entretainment.withdraw(152, &quot;trip to bcn&quot;)
def create_spend_chart(categories):
print(food.totalwithdrawals)
print(clothing.totalwithdrawals)
print(entretainment.totalwithdrawals)
#These three blocks of print is what i want to get
for i in categories:
i = Category(i)
print(i.totalwithdrawals)
#but when i loop through a list with the same names as the categories all i get is a bunch of 0s.
#Now i want to create a separate function that loops through a list of Categories and gives me 
# the total withdrawals for each one of them. The problem is that i cannot access the local
#variable &quot;totalwithdrawals&quot; (line 49). I want to get access for each item of list.
print(create_spend_chart([&quot;food&quot;, &quot;clothing&quot;, &quot;entretainment&quot;]))

I have started learning programming a month ago, so i am quite new to everything, i'll try to explain myself as good as i can. I've written a class called Category() with a bunch of methods and three different instances (food, clothing and entretainment).

I want to write a separate function (outside the class) that loops through a list of Categories (["food", "clothing", "entretainment"]) and prints the value of a local variable stored inside a method of the class Category(). The problem is that i cannot make python recognize the names of the list as the same names as the instances of the class. It's like if a name inside the list is "food" and there is also an instance of the class Category() named "food", instead of recognizing that both refer to the same, python seems to create a new duplicate object, and so instead of getting the value stored inside the local variable i get 0. I don't know how to explain better, if you run the code you will hopefully see it (check the commentaries of the code!)

答案1

得分: 0

A variable can just be accessed by its name. If you would want to pass a list of them:

print(create_spend_chart([food, clothing, entretainment]))

The loop in the function you do correctly, but with that loop i will become each one of them, so you don't have to refer to them individually anymore.

英文:

A variable can just be accessed by it's name. If you would want to pass a list of them:

print(create_spend_chart([food, clothing, entretainment]))

The loop in the function you do correctly, but with that loop i will become each one of them, so you don't have to refer to them individually anymore.

答案2

得分: 0

当你调用 i = Category(i) 时,你正在创建类的一个新实例。你不能用这种方式引用现有的实例。相反,你可以通过它们的名称引用你的类实例:

def create_spend_chart(categories):
    for category in categories:
        print(category.totalwithdrawals)

并调用它:

print(create_spend_chart([food, clothing, entertainment]))
英文:

When you calling i = Category(i) you are creating a new instance of the class. You cannot refer to existing instance this way. Instead, you can refer your class instances by their names:

def create_spend_chart(categories):
for category in categories:     
print(category.totalwithdrawals)

And call it with:

print(create_spend_chart([food, clothing, entretainment]))

答案3

得分: 0

看起来你对字符串和变量有些困惑。

create_spend_chart(["food", "clothing", "entertainment"])

上面的代码意味着你向 create_spend_chart 传递了一个字符串列表。这些字符串与先前声明的变量无关。

food = Category("food")
clothing = Category("clothing")
entertainment = Category("entertainment")

所以 food 并不等于 "food""food" 创建了一个字符串,而 food 是一个指向具有字段 name 内容为 "food" 的 Category 对象的变量。name 字段只是用来存储数据的字段,你不能通过这个字段的内容来调用变量。

create_spend_chart 中的循环为每次迭代创建了一个具有你在 categories 字符串列表中提供的名称的新 Category。这些都是新的类别对象,不是你之前声明的那些,所以最终你得到的 totalwithdrawals 值为0。

英文:

Looks like you are confused about strings and variables.

create_spend_chart([&quot;food&quot;, &quot;clothing&quot;, &quot;entretainment&quot;])

Above code means you pass in a list of string to create_spend_chat. These strings have nothing to do with previous variables declared.

food = Category(&quot;food&quot;)
clothing = Category(&quot;clothing&quot;)
entretainment = Category(&quot;entretainment&quot;)

So &quot;food&quot; is not food, &quot;food&quot; creates a string, food is a variable points to a Category object which happens to have a field called name with a content of &quot;food&quot;. The name field is just an field that stores data, you can't call the variable by this field's content.

The loop in create_spend_chart creates a new Category with a name you supplied in the categories list of string for each iteration. These are all new category objects, not the ones you declared before, so you ended up with totalwithdrawals of 0.

huangapple
  • 本文由 发表于 2023年2月27日 13:03:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/75576912.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定