Python: как вернуть экземпляр объекта вместе с атрибутами, назначенными с помощью setattr - PullRequest
1 голос
/ 09 августа 2011

Я все еще очень плохо знаком с Python, но мне нужно взаимодействовать с некоторым программным обеспечением, которое написано как набор модулей Python (файлы .py на случай, если я неправильно определил их как «модули».) Эта программа имеет несколько очень полезных и сложные функции, которые я действительно не могу реально взломать (если не что иное, потому что каждый раз, когда я обновляю программное обеспечение, мне придется все заново взламывать).

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

from software import thingfromsoftware
def mything(x,y,someboolean=True,etc)
    var=thingfromsoftware(x,y)
    #....code....
    setattr(var, 'dimensions', somearraything)
    return(var)

Тогда, если я попытаюсь:

result=mything(4,5)

затем result правильно содержит значения всех атрибутов, впервые присвоенных ему с помощью thingfromsoftware, но result.dimensions не было назначено (has no attribute "dimensions")

Цель состоит в том, чтобы хранить dimensions каждого result, вычисленного и сконфигурированного с помощью myfunctionthing некоторым полукогерентным образом.

Реальный код (по запросу)

from ase.structure import nanotube
from ase import Atoms, view, io
from numpy import *
from Avogadro import Molecule, MoleculeFile
import cPickle as pickle
import os


def make_nanotube(n,m,length=1,TYPE='free'):
    #This will set up leads so transport occures along the z axis and leads are aligned along the y axis (so they may be separated along the x axis.)

    os.chdir("/tmp")

    print 'Making ('+str(n)+','+str(m)+') nanotube with '+str(length)+" unit cell as "+str(TYPE)
    tube = nanotube(n, m, length=length, bond=1.420, symbol='C')
    center=tube.get_center_of_mass()
    name='tube:('+str(n)+', '+str(m)+'):unit cells:'+str(length)+':'+str(TYPE)+'.xyz'
    io.write(str(name), tube)

    print 'Computing bonds'
    mol = MoleculeFile.readMolecule(str(name))

    RELOAD=0
    for atom in mol.atoms[:]:
        if len(atom.bonds)<2 and atom.pos[-1]<center[-1]:
            print 'Relocating atom '+str(atom.index)+' from '+str(atom.pos[-1])+' to '+str(tube.get_cell()[-1, -1] + atom.pos[-1])
            tube.positions[atom.index, -1] += tube.get_cell()[-1, -1]
            RELOAD=1

    print 'Orienting tube'
    tip_atom=tube.get_positions()[:, -1].argmax() #the tip on the right (farther) end
    tip=tube.get_positions()[tip_atom]
    tube.rotate(append(tip[:-1], 0), append(center[0], zeros(2)), center=center) #rotate so that the tip is slanted toward x-axis (center[0],0,0)
    tube.center()
    setattr(tube, 'dimensions', [tube.get_cell()[0, 0]/2,tube.get_cell()[-1,-1]])
    cell=tube.get_cell()

    if TYPE!='bare':
        if RELOAD==1:
            print 'Recomputing bonds'
            io.write(str(name), tube)
            mol = MoleculeFile.readMolecule(str(name))

        print 'Adding hydrogens'
        mol.addHydrogens()

        if TYPE=='left lead':
            print 'Removing hydrogens from the right side'
            for atom in mol.atoms[:]:
                if atom.pos[2]<center[2]:
                    mol.removeHydrogens(atom)
        elif TYPE=='right lead':
            print 'Removing hydrogens from the left side'
            for atom in mol.atoms[:]:
                if atom.pos[2]>center[2]:
                    mol.removeHydrogens(atom)
        MoleculeFile.writeMolecule(mol,str(name))
        tube=io.read(str(name))
    else:
        tube.set_cell(cell)
    return(tube)

1 Ответ

1 голос
/ 09 августа 2011

Вы делаете

tube=io.read(str(name))

, если

TYPE!='bare'

Так что в этом случае вы не получите размеры.Может быть, поэтому у вас проблема?

Кроме того, вы пытались просто сделать

tube.dimensions = [tube.get_cell()[0, 0] / 2, tube.get_cell()[-1,-1]]

вместо setattr?Это необходимо только в том случае, если имя изменяемого атрибута хранится в имени переменной.

...