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

mik*_*keP 10 python matlab

在matlab中,我可以通过执行以下操作来创建结构数组(struct).

person.name = 'Mike';
person.age = 25;
person.gender = 'male';
Run Code Online (Sandbox Code Playgroud)

其中person在创建结构之前未定义.当我尝试在python中执行它时,它给了我一个错误

name 'person' is not defined
Run Code Online (Sandbox Code Playgroud)

在python中有类似的方法吗?谢谢

编辑:作为python的新手,我仍然在matlab中思考.我的问题是我有一个将需要多个输入(超过40)的函数,所以我没有函数(input1,input2,...,input40),我只需要输入函数(输入)由input.1,input.2,..,input.40组成.

Mat*_*lia 17

在Python中,您可以动态地向对象添加成员,但是(1)名称必须已经存在(必须已经分配)和(2)它必须绑定到某个类的实例.为此,您可以创建一个空类:

class Empty:
    pass        # empty statement otherwise the class declaration cannot succeed
Run Code Online (Sandbox Code Playgroud)

构造它的一个实例并将其分配给您的变量

person = Empty()
Run Code Online (Sandbox Code Playgroud)

然后添加您想要的任何数据

person.name = 'Mike'
person.age = 25
person.gender = 'male'
Run Code Online (Sandbox Code Playgroud)

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

person={}
person['name']='Mike'
person['age']=25
person['gender']='male'
Run Code Online (Sandbox Code Playgroud)

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

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


NPE*_*NPE 11

在Python中,person必须是某个类的实例; 它不能只是凭空实现.

您可以像这样实现与代码类似的东西:

class Struct(object): pass

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

print(person.__dict__)
Run Code Online (Sandbox Code Playgroud)

这打印:

{'gender': 'male', 'age': 25, 'name': 'Mike'}
Run Code Online (Sandbox Code Playgroud)

  • +1“不能凭空出现”:我的谷歌搜索“凭空创建Python实例”把我带到了这里! (2认同)

Vla*_*den 11

Python 3.3 添加了SimpleNamespace

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

SimpleNamespace 可用作类 NS: pass的替代品。但是,对于结构化记录类型,请改用 namedtuple()。

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

from types import SimpleNamespace

person = SimpleNamespace(name='Mike', age=25, gender='male')
print(person)
Run Code Online (Sandbox Code Playgroud)

输出:

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

from types import SimpleNamespace

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

print(person)
Run Code Online (Sandbox Code Playgroud)

输出:

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


kin*_*all 8

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

person.name = "Mike"
persom.age  = 25
person.sex  = "Male"
Run Code Online (Sandbox Code Playgroud)

现在我们有两个对象,person并且persom,和person没有age,也没有暗示这件事发生.后来你试图打印person.age,人们希望,matlab然后抱怨...在实际错误之后两页.

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

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

class person:
    name = "Mike"
    age  = 25
    sex  = sex.male
Run Code Online (Sandbox Code Playgroud)

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

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

当然,你仍然可以运行拼写错误的风险name,agesex在这种类型的类定义的.所以你可以做的是使用类作为模板并实例化它.

class Person:
    def __init__(self, name, age=None, sex=None):
        self.name, self.age, self.sex = name, age, sex
Run Code Online (Sandbox Code Playgroud)

现在你做的时候:

person = Person("Mike", 25, sex.male)
Run Code Online (Sandbox Code Playgroud)

或者如果您想记录所有这些参数是什么:

person = Person("Mike", age=25, sex=sex.male)
Run Code Online (Sandbox Code Playgroud)

最终不可能得到一个具有拼写错误的属性名称的对象.如果你搞砸了,Python会在你犯错的时候给你一个错误信息.这只是这样做的一个原因.


小智 5

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

person = {'name': 'Mike', 'age': 25}
Run Code Online (Sandbox Code Playgroud)