2017-01-05 28 views
0

我使用Python 3.6.0自动化在Cracker Barrel中找到的“三角挂钩游戏”,目前我正在用'turtle'实现它的图形。我创建的两个类与此问题相关:“游戏”(包含在主包中的模块中)和“TurtleGraphics”(包含在子包“图形”中的模块中)解释。当用'TurtleGraphics'对象作为参数调用'Game'对象时,两个对象相互链接,并调用'graphics._construct()',它定义了'Pen'对象并设置其'stretchfactor '使用'pen()'。这是问题出现的地方。尽管我在'turtle.cfg'文件中将'resizemode'设置为'user',但我必须再次将'resizemode'设置为'user'作为'pen()'的参数,以便图形构造当从游戏中被调用时适当。奇怪的是,如果我直接运行包含'TurtleGraphics'的模块并创建一个图形对象,它可以正常工作。另外,即使我从游戏对象中调用图形,也可以使用'shapesize()'而不是'pen()'来设置'stretchfactor'。首先,我将发布“Game .__ call__”和“TurtleGraphics._construct”的代码,并将每个代码与模块的import相关,这可能是相关的。我还会发布'TurtleGraphics .__ init__'和'TurtleGraphics._draw_board'。 (两个类都有基类,但'BaseGame'不处理图形,'Graphics'是抽象的,所以它们在这种情况下是不相关的。另外值得一提的是,'Game'没有'__init__'方法。所有的实例属性都是在调用时分配的。)然后,我将解释我迄今为止所做的研究。为什么我必须将'resizemode'设置为'user'两次,以便在使用'turtle'时我的'stretchfactor'更改生效?

游戏.__ call__:

from tripeg.graphics import Graphics 
from tripeg.graphics.ascii_ import ASCIIGraphics 
from tripeg.graphics.turtle_ import TurtleGraphics 

#... 

def __call__(self, graphics=None): 
    """Starts the game with given graphics, or none, if not given.""" 
    super().__call__() 
    if graphics: 
     if not isinstance(graphics, Graphics): 
      raise TypeError(f"Argument '{graphics}' is not of type" 
          " 'Graphics'.") 
     else: 
      self._graphics = graphics 
      self._graphics._game = self 
      self._graphics._construct() 

TurtleGraphics._construct:

import os 
import turtle 
from turtle import Screen, RawPen, Pen, Shape, Terminator, _CFG 

from tripeg.graphics import Graphics 

#... 

def __init__(self): 
    """Initialize self. See help(type(self)) for accurate signature.""" 
    os.chdir("C:\\Users\\Sylvaenn\\Python3.6.0\\Programs\\tripeg\\graphics") 
    turtle.readconfig("turtle.cfg") 

#... 

def _construct(self): 
    """Constructs the graphics for the game.""" 
    self.window = Screen() 
    self.window.setworldcoordinates(0,0,10,10) 
    self._draw_board() 

#... 

def _draw_board(self): 
    """Draws the game board.""" 
    wh_ratio = self.window.canvwidth/self.window.canvheight 

    tri_board = Shape("compound") 
    tri_board.addcomponent(((0,0),(8,0),(4,8)),(51,25,0),"black") 
    self.window.addshape("tri_board", tri_board) 

    board = Pen("tri_board") 
    board.pen(pendown=False, outline=7, stretchfactor=(60*wh_ratio,60)) 
    import pdb; pdb.set_trace() 
    board.setheading(90) 
    board.goto(1,1) 
    board.stamp() 

现在,这是我到目前为止已经发现:

我用 'PDB' 创建一个断点,在'pen()'被调用后直接放置它。当我运行游戏模块,并从游戏中调用图形,像这样......

>>> ga = Game() 
>>> gr = TurtleGraphics() 
>>> ga(gr) 
> c:\users\sylvaenn\python3.6.0\programs\tripeg\graphics\turtle_.py(82)._draw_board() 
-> board.setheading(90) 
(Pdb) !board.pen() 
{'shown': True, 'pendown': False, 'pencolor': 'black', 'fillcolor': 'black', 'pensize': 1, 'speed': 3, 'resizemode': 'noresize', 'stretchfactor': (71.46496815286623, 60), 'shearfactor': 0.0, 'outline': 7, 'tilt': 0.0} 
(Pdb) 

...“的stretchFactor”发生了变化,但“resizemode”仍尽管CFG文件设置为“noresize” 。

如果我运行的图形模块,并直接调用图形,像这样......

>>> gr = TurtleGraphics() 
>>> gr._construct() 
> c:\users\sylvaenn\python3.6.0\programs\tripeg\graphics\turtle_.py(82)_draw_board() 
-> board.setheading(90) 
(Pdb) !board.pen 
{'shown': False, 'pendown': False, 'pencolor': 'black', 'fillcolor': 'black', 'pensize': 1, 'speed': 3, 'resizemode': 'user', 'stretchfactor': (71.46496815286623, 60), 'shearfactor': 0.0, 'outline': 7, 'tilt': 0.0} 
(Pdb) 

...都“的stretchFactor”和“resizemode”具有预期值。

我已经尝试过:

  1. 分析 '龟' 的源代码,专门针对 '笔()', '_CFG' 和班 '海龟', 'RawTurtle',和其基类
  2. 同时使用IDLE调试器和广泛阅读在python.org和方法文档字符串教程
  3. 通过程序步骤跑一步“PDB”

正如我在开始时说,我可以使这项工作通过在'pen()'中包含“resizemode ='user'”以及cfg文件,或者使用'shapesize()'。这只是我想知道为什么我的cfg文件在所有情况下都没有达到预期的目的,我想更好地理解“turtle”模块和Python,如果我不明白为什么发生这种情况,我我确定我会遇到更严重的错误,我将无法修复它们。

+0

是的,我知道这篇文章是相当长的,但我宁愿精确而详细,比模糊和简洁。 –

+0

精确并不一定意味着详细。你已经付出了很多努力,我非常感谢你这样做。这使您从大量几乎不尝试的用户中脱颖而出。然而,在这么长的一篇文章中,几乎肯定有很多,你可以1)在不需要理解问题的“背景”部分中删除或隔离。相信我,我明白。一个很好的问题是,有很多草稿文本从未进入帖子中并不罕见。我认为如果您提供了*较少的上下文并将重点更多地放在了问题上,这篇文章会做得更好。 – jpmc26

+0

问好问题实际上很难,而且这是一项必须练习和掌握的技能。我可以告诉你有这样的动力;你所要做的就是继续尝试。 =)请在修改完这个问题后给我留个言,我想回来看看它。 – jpmc26

回答

1

我想知道为什么我的CFG文件是不是服务其预期目的在 所有情况下

这里是我的你的情况分析。你的代码的键位是这样的:

import turtle 
#... 
def __init__(self): 
    os.chdir("C:\\Users\\Sylvaenn\\Python3.6.0\\Programs\\tripeg\\graphics") 
    turtle.readconfig("turtle.cfg") 

有两点需要注意,可能不是很明显:

  1. turtle.readconfig()的参数将被忽略。相反,它看起来为 ,其源代码来自 * .py源文件所在的目录以及当前工作目录中的硬编码文件名“turtle.cfg”。在订购 。如果两个 都存在,则加载第二个优先级。 (还有第三个可能的配置文件,我不会去 到这里。)

  2. 如果os.chdir()而来的import turtle后,也不会看 你刚刚变成的目录中的配置文件。 os.chdir()必须在import turtle之前,如果您想要 它在chdir'd目录中查找。即使有显式调用 turtle.readconfig()

为了证明这第二点,先在一个临时目录中创建一个配置文件:

mkdir temporary_directory 
echo "resizemode = user" > temporary_directory/turtle.cfg 

运行这段代码:

import os 
import turtle 

from os.path import isfile 

current_directory = os.getcwd() 

os.chdir("temporary_directory") 

turtle.readconfig(None) 

print(turtle.resizemode()) 

你将会获得默认的noresize模式。使用此修改再次运行代码:

import os 

from os.path import isfile 

current_directory = os.getcwd() 

os.chdir("temporary_directory") 

import turtle 

turtle.readconfig(None) 

print(turtle.resizemode()) 

您将获得模式user

最后,如乌龟文档中所述,resizemode('user')shapesize()调用时,shapesize()被调用参数。

+0

我得到的结果并不符合你的答案,但从我阅读文档的时候,我认为他们会。我尝试了你的测试代码,而且我实际上都获得了“增量”。我在'pdb'中跑过'__init__','_CFG'用我的cfg文件进行了更新。实际上我发布代码后几个小时才开始工作。当我写完这篇文章时,我会在一篇文章中解释它。尽管如此,感谢您的反馈。至少,我知道我可以将'readconfig()'的参数改为'None',它的工作原理是一样的。 –

+0

@IsaacSaffold,因为我使用的是Unix,而且你使用的是Windows,并且涉及'os'模块,所以我想你的结果不一样让我感到惊讶。我很高兴你的工作有效,但我理解你的挫败感。 – cdlane

+0

它以同样的方式再次搞砸了(我仍然不知道我是如何暂时修复它的),而我只是把'os.chdir'放在'import turtle'上面,它就起作用了。毕竟,你的解决方案就是解决方案。我很感激。 –

相关问题