我打算组织并缩短后续版本,但为了记住6个月后的具体细微差别,我按时间顺序排除了它。
from random import *
class Card:
def __init__(self):
self.rank = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']
self.suit = ['s', 'h', 'c', 'd']
self.card = choice(rank) + choice(suit)
上面的代码在IDLE中运行。但是当我做>>> c = Card()[enter],我得到了下面的追溯。
Traceback (most recent call last):
File "<pyshell#18>", line 1, in <module>
c = Card()
File "C:\Current\MY_PYTHON\Py_OOP_progs\scrap2.py", line 7, in __init__
self.card = choice(rank) + choice(suit)
NameError: global name 'rank' is not defined
这是为什么?如果我将其更改为包含'return self.card',我也会获得几乎相同的追溯; '退卡;或者“返回”到类定义的末尾。如果我删除'自我'。来自变量(rank,suit和card)的前缀,然后它运行,我可以做&gt;&gt;&gt; c =卡()[输入];但是当我尝试做&gt;&gt;&gt; c.card [enter],我得到另一个追溯:
Traceback (most recent call last):
File "<pyshell#24>", line 1, in <module>
c.card
AttributeError: Card instance has no attribute 'card'
...这是我期望得到的,这也是我最初为rank,suit和card实例变量添加'self'前缀的原因。我想要得到的效果是,当我做&gt;&gt;&gt; c = Card()[enter],将c的卡实例变量设置为具有两个随机值:随机排名和随机诉讼,如原始代码所示。然后,我应该能够实例化52个Card()实例并在程序中稍后打印出来。这样做的传统方法是什么?注意 - 代码背后没有特别的含义 - 它几乎是任意的。我还没有完成OOP学习曲线,因此我没有阅读更多材料,而是认为如果我直接问我的错误,那么课程将更具互动性和难忘性。是否在代码中定义了一个必要的方法?
另外(只是一个猜测),除了获得更多实践经验编码类示例等之外,阅读python中“名称空间”和“范围”这两个区域可能是最相关的,以帮助我理解缺点上面的代码?
更多的实验(事后)与上述问题相关......代码:
from random import *
class Card:
rank = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']
suit = ['s', 'h', 'c', 'd']
card = choice(rank) + choice(suit)
...运行正常,但实例化Card(),&gt;&gt;&gt;之后的事实除外c.card [enter]每次都会给出相同的值。我终于得到了一些工作。以下代码:
class Card:
global rank
global suit
rank = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']
suit = ['s', 'h', 'c', 'd']
def make_Card(self):
card = choice(rank) + choice(suit)
print card
运行并允许我这样做:
>>> c = Card()
>>> c.make_Card()
5h
>>> c.make_Card()
4h
>>> c.make_Card()
2s
但是,我不知道。在最后一段代码中,我碰巧偶然发现了一种常规方法吗,因为我记得(模糊地)经常阅读有关声明全局变量的内容,在某些情况下设计很糟糕吗?
答案 0 :(得分:2)
第一个选项位于下一个代码部分:
from random import *
class Card:
def __init__(self):
self.rank = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']
self.suit = ['s', 'h', 'c', 'd']
self.card = choice(rank) + choice(suit)
改为:
self.card = choice(self.rank) + choice(self.suit)
由于变量rank
和suit
在您说self.card = choice(rank) + choice(suit)
时不存在,但self.rank
和self.suit
确实存在
另一种选择是:
class Card:
def __init__(self):
rank = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']
suit = ['s', 'h', 'c', 'd']
card = choice(rank) + choice(suit)
self.rank = rank
self.suit = suit
self.card = card
但我想第一个选择是pythonic
答案 1 :(得分:2)
您似乎在混淆O-O问题和Python语法问题。
你的队伍和职业不是对象;他们属于这个阶级;这是一个OO评论。
使用self
语法引用成员变量(这就是使用self
参数定义成员方法的原因):
class Card(object):
"""variables that are the same for all
Card instances"""
ranks = ['2', ..., 'A']
suits = ['s', 'h', 'c', 'd']
def __init__(self):
self.rank = choice(Card.ranks)
self.suit = choice(Cart.suits)
def card(self):
return self.rank + self.suit
def __repr__(self):
"""standard method to 'print' this object"""
return self.card()
请注意数据成员如何不丢失信息:检查两张卡是否来自同一套装是没有问题的:在rank + suit
解决方案中,您必须拆分self.card
和记得拿第二个项目,你只需要card.suit
这个设计。
现在您可以创建这样的卡片:
>>> c1 = Card()
>>> c2 = Card()
>>> cards = [ Card() for _ in xrange(0, 10) ]
玩得开心。
答案 2 :(得分:1)
存储在类实例中的任何变量都需要self.
前缀才能访问该变量。没有它,Python只在本地命名空间中查找,然后在全局命名空间中查找。在IDLE中,你可能以交互方式定义了一个rank或suit变量,类实例在全局命名空间中找到它。
解决问题:
from random import *
class Card:
def __init__(self):
self.rank = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']
self.suit = ['s', 'h', 'c', 'd']
# Access the instance's rank and suit.
self.card = choice(self.rank) + choice(self.suit)