В вашем a
классе my_hand
, other_hand
и hands
переменные являются все класса атрибутов (т.е. статических атрибутов), а не экземпляра атрибутов.
Также в вашем методе clear
вы переназначить my_hand
и other_hand
, но hands
по-прежнему ссылается на старые list
с, следовательно, его содержание не меняется. Если вы используете python3, вы должны использовать метод clear()
list
s: my_hand.clear()
и other_hand.clear()
, затем hands
будет ссылаться на два пустых list
. На python2 вы должны сделать del my_hand[:]
.
Если вы хотите присвоить атрибут , вам необходимо сделать self.attribute = value
. Для этого назначение должно быть помещено внутри метода __init__
, который является конструктором класса.
Как он в настоящее время стоит ваш код, если вы создадите два экземпляра a
, тогда они разделят руки, что, вероятно, то, что вы делаете не хотите.
Правильный код будет выглядеть так:
import random
class ClassesUseCamelCase(object):
# if you are using python2 do *not* forget to inherit object.
def __init__(self):
self.my_hand = []
self.other_hand = []
self.hands = [self.my_hand, self.other_hand]
def init_hands(self):
for round in range(5):
for hand in self.hands:
hand.append(round)
# or simpler:
# for hand in self.hands:
# hand.extend(range(5))
def shuffle(self):
random.shuffle(self.my_hand)
random.shuffle(self.other_hand)
def clear(self):
self.my_hand.clear() # or del self.my_hand[:] in python2
self.other_hand.clear()
Пример вывода с помощью IPython:
In [2]: inst = ClassesUseCamelCase()
In [3]: inst.init_hands()
In [4]: inst.shuffle()
In [5]: inst.hands
Out[5]: [[3, 2, 4, 0, 1], [3, 1, 4, 0, 2]]
In [6]: inst.clear()
In [7]: inst.hands
Out[7]: [[], []]
Заметьте, что он работает с более чем одним экземпляром:
In [9]: inst.init_hands()
In [10]: other = ClassesUseCamelCase()
In [11]: other.init_hands()
In [12]: inst.hands, other.hands
Out[12]: ([[0, 1, 2, 3, 4], [0, 1, 2, 3, 4]], [[0, 1, 2, 3, 4], [0, 1, 2, 3, 4]])
In [13]: inst.shuffle(); other.shuffle()
...:
In [14]: inst.hands
Out[14]: [[0, 1, 3, 2, 4], [1, 4, 0, 3, 2]]
In [15]: other.hands
Out[15]: [[1, 4, 2, 0, 3], [1, 4, 3, 2, 0]]
ваш код будет иметь разделили hands
между двумя экземплярами.
Я помещаю здесь немного больше объяснений о том, что происходит, чтобы избежать написания слишком большого количества комментариев.
Прежде всего, в вашем коде my_hand
и other_hand
являются классом атрибутов. Почему это имеет значение? Это важно, потому что атрибуты класса являются общими экземпляров:
In [1]: class MyClass(object):
...: my_hand = []
...: other_hand = []
...: hands = [my_hand, other_hand]
...:
In [2]: instance_one = MyClass()
In [3]: instance_two = MyClass()
In [4]: instance_one.my_hand.append(1)
In [5]: instance_two.my_hand # ops!
Out[5]: [1]
Вызова clear
изменяет атрибуты класса и, следовательно, все экземпляры их использование. Это, обычно, это то, что вы делаете не хотите.
В экземплярах Test нет атрибута другого экземпляра, что означает, что все экземпляры на самом деле равны; все они действуют одинаково и предоставляют одни и те же данные. Единственное различие заключается в их личности. Если вы не собираетесь использовать личность, то наличие класса и нескольких экземпляров бесполезно, потому что вы могли бы просто использовать один объект.
Если вы хотите, чтобы экземпляры имели свои собственные данные, независимо от данных других экземпляров, вам необходимо использовать атрибуты экземпляра.
Об утверждении del
. Как я уже сказал в комментариях, del
имеет два разных вида использования. полный синтаксис оператора является:
del sequence, of, del_targets
Если «последовательность из, del_targets» через запятую список того, что я буду называть del_targets
. В зависимости от del_target
поведение меняется.
Если это идентификтор, чем del
удаляет, что ссылки из сферы, декремент счетчика ссылок на объект, который был передан идентификатором.
Например:
a = b = []
# Now that empty list has two references: a and b
del b # now it has only one reference: a
print(b) # This raises a NameError because b doesn't exist anymore
del a # Now the empty list doesn't have references
Если объект не имеет ссылок он уничтоженные, поэтому после del a
над пустым списком будет уничтожен интерпретатором.
Мишень также может быть «индексом», то есть выражением, например name[key-or-index]
или name[a:slice]
(или name[start:stop:step]
). Синтаксис ломтиков (один с толстой кишкой) используется для указания диапазона индексов:
In [17]: numbers = list(range(10)) # [0, 1, ..., 9]
In [18]: numbers[::2], numbers[1::2], numbers[2:7:3]
Out[18]: ([0, 2, 4, 6, 8], [1, 3, 5, 7, 9], [2, 5])
При использовании del
заявления с таким выражением Python вызывает __delitem__
метод объекта, проходя в индексе или срезе , Это означает, что:
del numbers[:]
Средства: удалить все элементы списка numbers
, которые соответствуют индексу в срезе :
. Так как срез :
означает «все индексы в последовательности», результат опустошает список. Обратите внимание, что он не удалите ссылку из списка. Он действует только на его элементы.
Вы можете получить тот же эффект с помощью:
numbers[:] = []
Это говорит питона, чтобы заменить последовательность элементов, соответствующих срезу :
с элементами []
. Поскольку :
означает «все элементы» и []
пуст, эффект удаляет все элементы из списка. Этот синтаксис вызывает list.__setitem__
вместо list.__delitem__
под капотом, но результат тот же. Однако вы также можете сделать: numbers[:] = [2]
, а затем все элементы numbers
будут удалены и2
будет вставлен в результате списка [2]
.
Оба работают, однако я предпочитаю синтаксис del
, потому что он делает явные ваши намерения. Когда вы читаете:
del something[:]
Вы знаете, что заявление будет удалить что-нибудь. Затем вы видите индекс [:]
, и вы понимаете, что он удалит элементы из something
, а не ссылку something
. Однако, когда вы видите:
something[:] = []
Сначала вы думаете, хорошо это задание. Затем вы видите [:]
, и вы понимаете, что делаете «переписываете» содержимое списка. Затем вы смотрите на правую сторону и видите []
, поэтому мы собираемся перезаписать элементы пустым списком ... наконец, вы поймете, что оператор просто удалит все элементы из списка.
Часть кода в конце была отрезана. Он показал, что x.other_hand был [], тогда x.hands были [[1, 0, 4, 2, 3], [3, 4, 2, 0, 1]]. Извините –