2009-09-30 3 views
42

Очень просто, я учусь питона, и я не могу найти ссылку, которая говорит мне, как написать следующее:Как определить класс в Python

public class Team { 
    private String name; 
    private String logo; 
    private int members; 

    public Team(){} 

    // getters/setters 
} 

Позже:

Team team = new Team(); 
team.setName("Oscar"); 
team.setLogo("http://...."); 
team.setMembers(10); 

это класс команды со свойствами: имя/логотип/членов

Редактировать После нескольких попыток я получил это:

class Team: 
    pass 

Позже

team = Team() 
team.name="Oscar" 
team.logo="http://..." 
team.members=10 

Это питон путь ?? Чувствует нечетные (исходя из строго типизированного языка, конечно)

+0

Я хотел бы предложить, чтобы кто-то изменил название на то, что лучше для будущего поиска. Что-то вроде «Лучший способ определить класс в Python». – steveha

+0

@steveha: Может быть, хотя мой реальный вопрос был, как я пишу это в python ... как насчет ... – OscarRyz

ответ

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

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

+0

Мартин, какая разница между моим нахождением ** class Team: pass ** и ваш образец? – OscarRyz

+2

Вы можете динамически добавлять атрибуты по своему усмотрению, но если класс Team всегда будет содержать эти атрибуты, более ясно определить их внутри класса, а не извне. – monkut

+1

Это полезно для документации, так как позволяет людям, смотрящим ваш класс, видеть, какие атрибуты полезны. –

98

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

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, или по крайней мере идиому, которую вы должны овладеть.

+0

И если вы хотите, чтобы значения по умолчанию для строк были «" вместо «Нет», вы можете просто внести это изменение в функцию __init __(). – steveha

+0

+1 Интересно: если используются именованные параметры, я не получу «метод __init__ использует ровно 4 параметра, используемое 0» сообщение об ошибке ?? ... – OscarRyz

+8

+1: классы нового стиля –

Смежные вопросы