Вот что я бы рекомендовал:
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)
Некоторые замечания по этому вопросу.
0) Я объявил, что команда наследует от object
. Это делает команду «классом нового стиля»; это было рекомендовано в Python, так как оно было введено в Python 2.2. (В Python 3.0 и выше классы всегда «нового стиля», даже если вы не указываете нотацию (object)
, но эта нотация не наносит вреда и делает наследование явным.) Вот класс StackOverflow discussion классов нового стиля.
1) Это не требуется, но я заставил инициализатор принять дополнительные аргументы, чтобы вы могли инициализировать экземпляр в одной строке, как и в случае с team
и team3
. Эти аргументы называются, поэтому вы можете либо предоставить значения в качестве позиционных параметров (например, team
), либо вы можете использовать форму argument=
, как и в случае с team3
. Когда вы явно укажете имя аргументов, вы можете указать аргументы в любом порядке.
2) Если вам нужно иметь функции getter и setter, возможно, что-то проверить, в Python вы можете объявить специальные функции метода. Это то, что имел в виду Мартин против Лёвиса, когда он сказал «дескрипторы свойств». В Python обычно считается хорошей практикой просто назначать переменные-члены и просто ссылаться на их выборку, потому что вы всегда можете добавить в дескрипторы свойств позже, если они вам понадобятся. (И если вы не нуждаетесь в них, то ваш код менее загроможден и принял вас меньше времени, чтобы написать Bonus.!)
Вот хорошая ссылка про дескрипторы собственности: http://adam.gomaa.us/blog/2008/aug/11/the-python-property-builtin/
3) Это действительно не если вы укажете значения как часть вызова 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
, но этого не происходит по умолчанию.)
EDIT: Я оставил одну вещь в выше ответ, и я хотел бы добавить его сейчас. Если вы выполняете необязательную аргументацию в функции __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
Главное, что вам нужно знать: необязательные аргументы оцениваются только один раз, когда функция скомпилирована. Поэтому, если вы передаете mutable как необязательный аргумент в __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 "[]"
Это бизнес, используя значение аргумента по умолчанию None
, затем проверить, что аргумент, передаваемый is None
, квалифицируется как шаблон проектирования Python, или по крайней мере идиому, которую вы должны овладеть.
Я хотел бы предложить, чтобы кто-то изменил название на то, что лучше для будущего поиска. Что-то вроде «Лучший способ определить класс в Python». – steveha
@steveha: Может быть, хотя мой реальный вопрос был, как я пишу это в python ... как насчет ... – OscarRyz