Как определить класс в Python?

Вот быстрое решение до сих пор (для следующего входа):

def del_dups(seq):
    seen = {}
    pos = 0
    for item in seq:
        if item not in seen:
            seen[item] = True
            seq[pos] = item
            pos += 1
    del seq[pos:]

lst = [8, 8, 9, 9, 7, 15, 15, 2, 20, 13, 2, 24, 6, 11, 7, 12, 4, 10, 18, 
       13, 23, 11, 3, 11, 12, 10, 4, 5, 4, 22, 6, 3, 19, 14, 21, 11, 1, 
       5, 14, 8, 0, 1, 16, 5, 10, 13, 17, 1, 16, 17, 12, 6, 10, 0, 3, 9, 
       9, 3, 7, 7, 6, 6, 7, 5, 14, 18, 12, 19, 2, 8, 9, 0, 8, 4, 5]
del_dups(lst)
print(lst)
# -> [8, 9, 7, 15, 2, 20, 13, 24, 6, 11, 12, 4, 10, 18, 23, 3, 5, 22, 19, 14, 
#     21, 1, 0, 16, 17]

Поиск по словарю немного быстрее тогда один набора в Python 3.

55
задан peterh says reinstate Monica 1 February 2019 в 14:46
поделиться

2 ответа

class Team:
  def __init__(self):
    self.name = None
    self.logo = None
    self.members = 0

В Python вы обычно не пишете геттеры и сеттеры, если только у вас нет для них нетривиальной реализации (в этот момент вы используете дескрипторы свойств).

55
ответ дан 26 November 2019 в 17:40
поделиться

Вот что я бы порекомендовал:

class Team(object):
    def __init__(self, name=None, logo=None, members=0):
        self.name = name
        self.logo = logo
        self.members = members

team = Team("Oscar", "http://...", 10)

team2 = Team()
team2.name = "Fred"

team3 = Team(name="Joe", members=10)

Некоторые примечания по этому поводу:

  1. I объявил, что Team наследуется от объекта . Это делает Team «классом нового стиля»; это рекомендовано в Python с момента появления в Python 2.2. (В Python 3.0 и более поздних версиях классы всегда относятся к «новому стилю», даже если вы опускаете нотацию (object) ; но наличие этой нотации не вредит и делает наследование явным.) Вот StackOverflow обсуждение классов нового стиля.

  2. Это не обязательно, но я заставил инициализатор принимать необязательные аргументы, чтобы вы могли инициализировать экземпляр в одной строке, как я сделал с командой и team3 . Эти аргументы названы, поэтому вы можете либо указать значения в качестве позиционных параметров (как в team ), либо вы можете использовать форму argument = , как я сделал с team3 . Когда вы явно указываете имя аргументов, вы можете указывать аргументы в любом порядке.

  3. Если вам нужны были функции получения и установки, возможно, чтобы что-то проверить, в Python вы можете объявить специальные функции методов. Именно это имел в виду Мартин против Лёвиса, когда говорил о «дескрипторах собственности». В Python обычно считается хорошей практикой просто назначать переменным-членам и просто ссылаться на них для их получения, потому что вы всегда можете добавить дескрипторы свойств позже, если они вам понадобятся. (А если они вам никогда не понадобятся, тогда ваш код будет менее загроможден и вам потребуется меньше времени на написание. Бонус!)

    Вот ' хорошая ссылка о дескрипторах свойств: http://adam.gomaa.us/blog/2008/aug/11/the-python-property-builtin/

  4. Не имеет особого значения, если вы указываете значения как часть вызова Team () или если вы позже вставите их в свой экземпляр класса. Последний экземпляр класса, который у вас получится, будет идентичным.

team = Team("Joe", "http://example.com", 1)
team2 = Team()
team2.name = "Joe"
team2.logo = "http://example.com"
team2.members = 1

print team.__dict__ == team2.__dict__

Выше будет напечатано True . (Вы можете легко перегрузить оператор == для экземпляров Team и заставить Python поступать правильно, когда вы говорите team == team2 , но это не так происходит по умолчанию.)


РЕДАКТИРОВАТЬ: Я упустил одну вещь в приведенном выше ответе, и я хотел бы добавить ее сейчас. Если вы используете необязательный аргумент в функции __ init __ () , вам нужно быть осторожным, если вы хотите предоставить "изменяемый" как необязательный аргумент.

Целые числа и строки «неизменяемы». Вы никогда не сможете поменять их на месте; вместо этого происходит то, что Python создает новый объект и заменяет тот, который был у вас раньше.

Списки и словари «изменяемы». Вы можете хранить один и тот же объект вечно, добавляя к нему и удаляя из него.

x = 3   # the name "x" is bound to an integer object with value 3
x += 1  # the name "x" is rebound to a different integer object with value 4

x = []  # the name "x" is bound to an empty list object
x.append(1)  # the 1 is appended to the same list x already had

Ключевой момент, который вам нужно знать: необязательные аргументы оцениваются только один раз, когда функция компилируется. Поэтому, если вы передадите изменяемый объект в качестве необязательного аргумента в __ init __ () для вашего класса, то каждый экземпляр вашего класса будет использовать один изменяемый объект. Это почти никогда не то, что вам нужно.

class K(object):
    def __init__(self, lst=[]):
        self.lst = lst

k0 = K()
k1 = K()

k0.lst.append(1)

print k0.lst  # prints "[1]"
print k1.lst  # also prints "[1]"

k1.lst.append(2)

print k0.lst  # prints "[1, 2]"

Решение очень простое:

class K(object):
    def __init__(self, lst=None):
        if lst is None:
            self.lst = []  # bind lst with a new, empty list
        else:
            self.lst = lst # bind lst with provided list

k0 = K()
k1 = K()

k0.lst.append(1)

print k0.lst  # prints "[1]"
print k1.lst  # print "[]"

Это дело использования значения аргумента по умолчанию Нет , а затем проверки того, что переданный аргумент - Нет ],

110
ответ дан 26 November 2019 в 17:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: