什么是Pythonic按名称初始化,设置和获取自定义对象属性的方法?

djc*_*476 10 python attributes properties object

我是Python的新手,我需要声明我自己的数据结构,但我对如何做到这一点有点困惑.我目前有:

class Particle:

    def __init__(self, mass, position, velocity, force):

        self.mass = mass
        self.position, self.velocity, self.force = position, velocity, force

    def __getitem__(self, mass):
        return self.mass

    def __getitem__(self, position):
        return self.position

    def __getitem__(self, velocity):
        return self.velocity

    def __getitem__(self, force):
        return self.force
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试使用以下方法定义类的实例时,这不起作用:

 p1 = Particle(mass, position, velocity, force)
Run Code Online (Sandbox Code Playgroud)

每个值最终都是(0.0,0.0)(这是速度和力的值).

有人可以解释我出错的地方,我需要的数据结构就是能够从中提取数据,没有别的.(编辑:实际上,对不起,稍后我将不得不改变它们)

谢谢

Dav*_*arx 20

首先,你应该明白这__getitem__是语法糖.很高兴有,但如果你不需要它,不要使用它.__getitem__并且__setitem__基本上如果您希望能够使用括号表示法从对象访问项目,例如:

p= Particle(foo)
bar = p[0]
Run Code Online (Sandbox Code Playgroud)

如果你不需要这个,不要担心.

现在,到其他一切.看起来你已经拥有了你希望你的对象在你的__init__定义中随身携带的主要特征,这很好.现在,您需要使用self以下方法将这些值实际绑定到对象:

class Particle:
    def __init__(self, mass, position, velocity, force):
        self.mass = mass
        self.position = position
        self.velocity = velocity
        self.force = force
Run Code Online (Sandbox Code Playgroud)

真的是这样的.您现在可以使用点表示法访问这些值,如下所示:

mass,pos,vel,f = 0,0,0,0 # just for readability
p = Particle(mass,pos,vel,f)
print p.mass, p.position, p.velocity, p.force
Run Code Online (Sandbox Code Playgroud)

我们得到的一个好处是,如果我们问python是什么p,它会告诉你它是Particle类型的一个实例,如下所示:

in [1]: p
out[1]: <__main__.Particle instance at 0x03E1fE68>
Run Code Online (Sandbox Code Playgroud)

理论上,当您使用这样的对象时,您希望在用户和数据之间存在"抽象层",这样它们就不会直接访问或操作数据.为此,您可以创建函数(就像您尝试过的那样__getitem__),通过类方法调解用户和数据之间的交互.这很好,但通常没有必要.

在更简单的情况下,要更新这些属性的值,您可以直接以与访问它们相同的方式执行此操作,使用点表示法:

in [2]: p.mass
out[2]: 0

in [3]: p.mass = 2 
in [4]: p.mass
out[4]: 2
Run Code Online (Sandbox Code Playgroud)

你可能已经想到了这一点,但是关于__init__函数,甚至是class定义(你通常应该/通常应该定义你的类的大部分属性和方法)并没有什么神奇之处.某些类型的对象非常宽松,允许您随时随地添加属性.这可能很方便,但一般来说非常hacky并不是很好的做法.我不是建议你这样做,只是向你展示它是可能的.

in [5]: p.newattr ='foobar!'
in [6]: p.newattr
out[6]: 'foobar!'
Run Code Online (Sandbox Code Playgroud)

奇怪吧?如果这让你的皮肤爬行......好吧,也许它应该.但这是可能的,我应该说出你能做什么,不能做什么.这样就可以了解课程的运作方式.


Wal*_*han 8

class Particle:
    def __init__(self, mass, position, velocity, force):
        self.mass = mass
        self.position = position
        self.velocity = velocity
        self.force = force

particle = Particle(1, 2, 3, 4)
print(particle.mass)  # 1
Run Code Online (Sandbox Code Playgroud)

如果你想假装你的类有属性,你可以使用@property装饰器:

class Particle:
    def __init__(self, mass, position, velocity, force):
        self.mass = mass
        self.position = position
        self.velocity = velocity
        self.force = force

    @property
    def acceleration(self):
        return self.force / self.mass

particle = Particle(2, 3, 3, 8)
print(particle.acceleration)  # 4.0
Run Code Online (Sandbox Code Playgroud)