在不调用类的情况下创建对象

时间:2012-01-20 22:38:51

标签: python matlab

在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.1,input.2,..,input.40组成。

6 个答案:

答案 0 :(得分:15)

在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'

另一方面,如果您不需要“普通”类提供的附加功能,并且您只想以key =>值方式存储某些数据,则应该只使用字典。

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

(请注意,至少在Python 2.7之前,这主要只是一种风格/语法差异,因为实例成员是在字典方面实现的)

作为一般准则,当您实例化以相同方式制作的多个对象时,您需要类(通常在类构造函数中完成对成员的赋值;稍后添加成员通常会导致难以遵循的代码),否则就是字典。

答案 1 :(得分:10)

当你开始为它分配属性时,Python不会神奇地创建一个容器对象,如果matlab允许这样做,我会认为matlab严重破坏了。考虑一下:

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

现在我们有两个对象,personpersom,而person没有age,并且没有提示发生这种情况。< / em>稍后你试图打印person.age,人们希望,matlab然后抱怨......在实际错误之后两页。

一个类本身可以用作容器或命名空间。没有必要实例化它,如果您只想要一组属性,它会为您节省一些输入。

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

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

要访问或修改其中任何一项,您可以使用person.name

N.B。我还使用sex类来说明这样做的好处之一:它提供了数据值的一致性(不记得你是使用“M”还是“男性”还是“男性”)并捕获错别字(即Python会抱怨sex.mlae但不是关于字符串“mlae”,如果你后来检查它反对“男性”,后者会失败)。

当然,在此类类定义中,您仍然存在拼写错误nameagesex的风险。所以你可以做的是使用类作为模板并实例化它。

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会在你犯错的时候给你一个错误信息。这只是这样做的一个原因。

答案 2 :(得分:9)

在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'}

答案 3 :(得分:4)

Python 3.3添加了SimpleNamespace

与对象不同,使用SimpleNamespace可以添加和删除属性。 如果使用关键字参数初始化了SimpleNamespace对象, 这些将直接添加到基础名称空间。

SimpleNamespace可以代替 NS类:通过。 但是,对于结构化记录类型,请改用namedtuple()。

以下是如何使用它的示例:

from types import SimpleNamespace

person = SimpleNamespace(name='Mike', age=25, gender='male')
print(person)

输出:

命名空间(年龄= 25,性别=“男性”,名字=“迈克”)

from types import SimpleNamespace

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

print(person)

输出:

命名空间(年龄= 25,性别=“男性”,名字=“迈克”)

答案 4 :(得分:3)

你可能想要一个字典(散列,关联数组):

person = {'name': 'Mike', 'age': 25}

答案 5 :(得分:1)

虽然我建议使用NPE或Matteo作为首选方法,因为函数是python中的第一类对象,它们也可以用来模拟一个空类,但它们不能被实例化为多个对象(所以你只能有一个每个函数的对象实例)。

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

这很奇怪,所以我不建议使用它,但它确实说明函数是python中的第一类对象。