Создать объект без вызова класса - PullRequest
10 голосов
/ 21 января 2012

В Matlab я могу создать структурный массив (struct), выполнив следующие действия:

person.name = 'Mike';
person.age = 25;
person.gender = 'male';

, где person не определен до создания структуры.Когда я пытаюсь сделать это в Python, он выдает ошибку

name 'person' is not defined

Есть ли подобный способ сделать это в Python?Спасибо

РЕДАКТИРОВАТЬ: Будучи новичком в Python, я все еще думаю, в Matlab.У меня проблема в том, что у меня есть функция, которая будет принимать несколько входов (более 40), поэтому вместо функции (input1, input2, ..., input40) у меня будет просто функция (input), где входсостоят из input.1, input.2, .., input.40.

Ответы [ 5 ]

17 голосов
/ 21 января 2012

В Python вы можете динамически добавлять члены к объекту, но (1) имя должно уже существовать (оно должно быть назначено) и (2) оно должно быть привязано к экземпляру некоторого класса. Для этого вы можете создать пустой класс:

class Empty:
    pass        # empty statement otherwise the class declaration cannot succeed

создайте его экземпляр и назначьте его переменной

person = Empty()

и затем добавьте любые данные, которые вы хотите

person.name = 'Mike'
person.age = 25
person.gender = 'male'

С другой стороны, если вам не нужны дополнительные функции, которые предоставляет «нормальный» класс, и вы просто хотите хранить некоторые данные в ключе => значение, вам, вероятно, следует просто использовать словарь.

person={}
person['name']='Mike'
person['age']=25
person['gender']='male'

(обратите внимание, что, по крайней мере, до Python 2.7, это в основном просто стилистическое / синтаксическое различие, поскольку члены экземпляра реализованы ниже в терминах словарей)

В качестве общего руководства, вам нужны классы, когда вы создаете экземпляры нескольких объектов, созданных одинаковым образом (и где обычно присваивание членам выполняется в конструкторе классов; позднее добавление членов обычно затрудняет выполнение кода), словари в противном случае.

11 голосов
/ 21 января 2012

В Python person должен быть экземпляром некоторого класса;он не может просто материализоваться из воздуха.

Вы можете достичь чего-то похожего на ваш код, например:

class Struct(object): pass

person = Struct()
person.name = 'Mike'
person.age = 25
person.gender = 'male'

print(person.__dict__)

Это печатает:

{'gender': 'male', 'age': 25, 'name': 'Mike'}
9 голосов
/ 21 января 2012

Python не будет волшебным образом создавать контейнерный объект, когда вы начнете присваивать ему атрибуты, и если matlab позволяет это, я считаю, что matlab сильно поврежден. Учтите это:

person.name = "Mike"
persom.age  = 25
person.sex  = "Male"

Теперь у нас есть два объекта, person и persom, и person не имеет age, , и не было никаких намеков на то, что это произошло. Позже вы пытаетесь напечатать person.age и, можно надеяться, тогда Матлаб жалуется ... через две страницы после фактической ошибки.

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

class sex:
    male   = "M"
    female = "F"

class person:
    name = "Mike"
    age  = 25
    sex  = sex.male

Чтобы получить доступ к любому из них или изменить его, вы можете использовать person.name и т. Д.

N.B. Я также использовал класс для sex, чтобы проиллюстрировать одно из преимуществ этого: он обеспечивает согласованность значений данных (не помня, использовали ли вы «M», «Male» или «male») и ловит опечатки (например, Python). будет жаловаться на sex.mlae, но не на строку «mlae», и если вы позже проверите ее на «мужчина», последняя потерпит неудачу).

Конечно, вы все еще рискуете ошибиться в написании name, age или sex в этом типе определения класса. Поэтому вы можете использовать класс в качестве шаблона и создать его экземпляр.

class Person:
    def __init__(self, name, age=None, sex=None):
        self.name, self.age, self.sex = name, age, sex

Теперь, когда вы делаете:

person = Person("Mike", 25, sex.male)

или если вы хотите задокументировать, что это за параметры:

person = Person("Mike", age=25, sex=sex.male)

практически невозможно получить объект с ошибочным именем атрибута. Если вы ошибетесь, Python выдаст вам сообщение об ошибке в тот момент, когда вы допустили ошибку. Это всего лишь одна из причин сделать это таким образом.

4 голосов
/ 21 января 2012

Возможно, вам нужен словарь (хэш, ассоциативный массив):

person = {'name': 'Mike', 'age': 25}
1 голос
/ 12 августа 2014

Хотя я бы порекомендовал NPE или Matteo в качестве предпочтительного метода, поскольку функции являются объектами первого класса в python, их также можно использовать для эмуляции пустого класса, но их нельзя создавать как несколько объектов (поэтому у вас будет только один экземпляр объекта на функцию).

>>> def person():pass
...
>>> person.name = 'Mike'
>>> person.name
'Mike'
>>> person
<function person at 0x020CF2F0>

Это странно, поэтому я бы не рекомендовал использовать это, но оно иллюстрирует, что функции являются объектами первого класса в python.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...