我无法在类外部获得定义的var,以便在类中定义var

时间:2015-07-16 18:03:22

标签: python class

我刚刚发布了这个,但我已经清理了一下,从那时起,问题仍然存在,因为没有人真的给出了正确的答案。 所以我的问题是,我在课堂外定义的变量和循环stonepilewoodpile(在一个类中)并不是stone / {{ 1}}(也在同一个类中)对自己多次,我知道这是因为我得到要打印的wood / stonepile。我已经测试过,每次被告知要将woodpile / stonepile添加到woodpile /时,问题实际上是stone / wood重置stonepile。我知道这是因为我和他们一起这样做了:

woodpile

结果是如果开采的石头是1并且x的randint是5,那么它将打印6.或类似的东西。 那么有什么方法可以解决吗?

这里的整个代码:

y = random.randint(1,5)
x = random.randint(1,5)
woodpile = y
stonepile = x

4 个答案:

答案 0 :(得分:1)

如果要修改函数(或类函数)中的全局,则需要使用全局

foo = 0
def afunc():
    global foo
    foo = 1

afunc()
print foo

全局变量的名称与类内部的名称相同。我注意到您可能希望woodpile += wood

完成self.woodpile += wood的某些地方

答案 1 :(得分:0)

您可以找到一种在while idle循环之外实例化变量的方法。我会尝试不将tasknum作为您的__init__输入变量之一

class Taskassigner:
        def __init__(self,stonepile,woodpile):
            self.tasknum = 0
            self.woodpile = woodpile
            self.stonepile = stonepile

因为你不能砍石头或采伐木材,所以你不必将它们包括在你的所有方法中。 即。

def chop(self):
            wood = random.randint(1, 10)
            print('chopping wood')
            time.sleep(1.5)
            print('you got', wood)
            self.woodpile += wood
            print(self.woodpile)
            time.sleep(0.75)

def choosejob(self):
            if self.tasknum == 1:
                self.chop()
            if self.tasknum == 2:
                self.mine()

然后你可以打电话:

job = Taskassigner(tasknum,stonepile,woodpile)

while idle:
        taskchance = random.randint(0,1)
        if taskchance == 1:
            job.tasknum = random.randint(0,2)
            job.choosejob()
            print
        else:
            print('idle')
            time.sleep
            (0.5)

答案 2 :(得分:0)

这就是我的工作代码的外观:

import random
import time
idle = True
woodpile=0
stonepile=0


class Taskassigner:
    def __init__(self,tasknum):

        self.tasknum = tasknum
        self.choosejob(tasknum)
    def choosejob(self,tasknum):

        if self.tasknum == 1:
            self.chop()
        if self.tasknum == 2:
            self.mine()
    def chop(self):

        global woodpile
        wood = random.randint(1, 10)
        print('chopping wood')
        time.sleep(1.5)
        print('you got', wood)
        woodpile += wood
        print(woodpile)
        time.sleep(0.75)
    def mine(self):

        global stonepile
        stone = random.randint(1, 10)
        print('mining for stone')
        time.sleep(1.5)
        print('you got', stone)
        stonepile += stone
        print(stonepile)
        time.sleep(0.75)


while idle:

    taskchance = random.randint(0,1)
    if taskchance == 1:
        tasknum = random.randint(0,2)
        Taskassigner(tasknum)
    else:
        print('idle')
        time.sleep(0.5)

答案 3 :(得分:0)

以下是我认为你要做的事情:

woodpile = 0
stonepile = 0

some_task = TaskAssigner(...)
some_task.chop()

woodpile == 3  # True

你真的不希望如此。你永远不希望你的方法或函数影响他们没有明确交付的东西,因为它使调试非常非常。相反,你应该做类似的事情:

class Stockpile(object):
    def __init__(self, starting_wood=0, starting_stone=0):
        self.woodpile = starting_wood
        self.stonepile = starting_stone

class TaskAssigner(object):
    def __init__(self, stockpile):
        self.stockpile = stockpile

    def mine(self):
        quantity = random.randint(1,5)
        self.stockpile.stonepile += quantity

    def chop(self):
        quantity = random.randint(1,5)
        self.stockpile.woodpile += quantity

    def do_task(self):
        if random.randint(0, 1):  # 50% chance
            random.choice([self.mine, self.chop])()
            # do either self.mine or self.chop

stockpile = Stockpile()

taskmaster = TaskAssigner(stockpile)

while True:
    if idle:
        taskmaster.do_task()

通过执行以下操作,您可能会使这更加模块化:

from types import MethodType
import random

class TaskAssigner(object):
    def __init__(self, stockpile):
        self.stockpile = stockpile
        self.tasks = []

    def make_task(self, attr_to_change, delta_min, delta_max, f_name):
        def f(self):
            qty = random.randint(delta_min, delta_max)
            new_total = getattr(self.stockpile, attr_to_change) + qty
            setattr(self.stockpile, attr_to_change, new_total)
        f.__name__ = f_name
        f = MethodType(f, self)
        setattr(self, f_name, f)
        self.tasks.append(f)

    def do_task(self):
        if random.randint(0, 1):
            random.choice(self.tasks)()

然后你可以这样做:

class Stockpile(object):
    def __init__(self, starting_wood=0, starting_stone=0, starting_grain=0):
        self.woodpile = starting_wood
        self.stonepile = starting_stone
        self.grainsilo = starting_grain

stockpile = Stockpile()
tasks = TaskAssigner(stockpile)

tasks.make_task('woodpile', 1, 5, 'chop_wood')
tasks.make_task('stonepile', 1, 5, 'mine_stone')
tasks.make_task('grainsilo', 2, 10, 'harvest_grain')

tasks.harvest_grain()  # adds to stockpile.grain_silo!
tasks.do_task()  # 50% does nothing, 50% does one of the three!

但请注意,这是非常先进的,除非您深入了解它,否则我强烈建议您此时不要尝试这种元编程