Python 我能';t在类外部获取已定义的变量以添加在类内部定义的变量
我不久前发布了这个,但我已经清理了一点,从那以后,问题仍然存在,因为没有人真正给出正确的答案。 所以我的问题是,我在类外定义的变量和循环Python 我能';t在类外部获取已定义的变量以添加在类内部定义的变量,python,class,Python,Class,我不久前发布了这个,但我已经清理了一点,从那以后,问题仍然存在,因为没有人真正给出正确的答案。 所以我的问题是,我在类外定义的变量和循环stonepile和woodpile(在类内)没有多次向自身添加stone/wood(也在同一类内),我知道这一点,因为我得到了要打印的stonepile/woodpile。我已经测试过,问题实际上是开始时的stonepile/woodpile,每次被告知将stone/wood添加到stonepile/中时都会重置。我知道这一点,因为我和他们一起做过: y =
stonepile
和woodpile
(在类内)没有多次向自身添加stone
/wood
(也在同一类内),我知道这一点,因为我得到了要打印的stonepile
/woodpile
。我已经测试过,问题实际上是开始时的stonepile
/woodpile
,每次被告知将stone
/wood
添加到stonepile
/中时都会重置。我知道这一点,因为我和他们一起做过:
y = random.randint(1,5)
x = random.randint(1,5)
woodpile = y
stonepile = x
结果是,如果开采的石头是1,x的randint是5,它将打印6。或者类似的东西。
有没有办法解决这个问题
整个代码如下:
import random
import time
idle = True
woodpile = 0
stonepile = 0
while True:
class Taskassigner:
def __init__(self,tasknum,stonepile,woodpile):
self.tasknum = tasknum
self.woodpile = woodpile
self.stonepile = stonepile
def choosejob(self,stonepile,woodpile):
if self.tasknum == 1:
self.chop(woodpile)
if self.tasknum == 2:
self.mine(stonepile)
def chop(self,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,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)
job = Taskassigner(tasknum,stonepile,woodpile)
job.choosejob(stonepile,woodpile)
print
else:
print('idle')
time.sleep(0.5)
如果要修改函数(或类函数)中的全局变量,则需要使用全局变量
foo = 0
def afunc():
global foo
foo = 1
afunc()
print foo
全局变量的名称与类内部的名称相同。我注意到一些地方,当您可能想要self.woodpile+=wood
时,您在那里执行了woodpile+=wood
,您可以找到一种方法,在循环空闲时在外部实例化变量。我会尝试不将tasknum作为\uuuuu init\uuuu
输入变量之一
class Taskassigner:
def __init__(self,stonepile,woodpile):
self.tasknum = 0
self.woodpile = woodpile
self.stonepile = stonepile
此外,由于你不能砍石头或矿山木材,你不必把他们包括在你的所有方法。
i、 e
然后你可以打电话:
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)
以下是我的工作代码的外观:
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)
以下是我认为您正在尝试的:
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):
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!
但是请注意,这是非常高级的,除非您深入理解它,否则我强烈建议您此时不要尝试这种元编程为什么您的类定义在循环中?在\uuuu init\uuuu()
中,您连续分配self.woodpile
两次,为什么?我修复了它,但它仍然没有做我想让它做的事嘿@FlyingNat,是我回答了你的问题。我留下了什么不清楚的地方?你好,我可能没有说清楚,我只是想让它工作起来,这样我知道我可以正确地编写代码,让它按照我想要的方式工作。我很抱歉,因为我觉得你不会喜欢我,因为我没有利用你的想法。我是青少年,请原谅我的语法和孩子气。如果你想知道我的问题,请阅读这个问题。谢谢你,我会改进我的编码,如果它有效,我会同意答案。再次感谢你。虽然这会起作用,但这是一个糟糕的设计选择。您应该尽可能避免global
,因为它破坏了封装。它可以工作!!!谢谢你的帮助。我在类中使这两个变量都是全局的,但它得出了这样的结论:“SyntaxError:name'woodpile'是parameter and global.”所以我从类的所有参数中删除了这两个变量,现在它按照我希望的方式工作了。我将它修好了一点点,得到了这个结果:random.choice(self.my,self.chop)()TypeError:choice()接受2个位置参数,但有3个是given@FlyingNat哎呀,修好了。我总是认为是随机的。choice
接受*args
,但它实际上只接受一个选项列表。“object”是干什么的?顺便说一句,谢谢您的帮助!这次你帮了大忙。“对不起,我不是故意小气的。@FlyingNat你听起来不小气!”!问问题很好!应该回答为什么我使用类名(对象)
而不是类名
。这只是习惯,因为Python3默认使用新样式的类。这有什么问题吗?有什么我可以收紧的吗?请反馈我的工作代码