开发者

Python: How to return an instance of an object along with attributes assigned with setattr

开发者 https://www.devze.com 2023-03-26 21:33 出处:网络
I am still very new to python, but I need to interface with some software that is written as a bunch of python modules (.py files in case I incorrectly identified them as \"modules.\") This program ha

I am still very new to python, but I need to interface with some software that is written as a bunch of python modules (.py files in case I incorrectly identified them as "modules.") This program has some very useful and complicated functions that I really cannot feasibly hack (if nothing else, because every time I update the software, I will have to re-hac开发者_C百科k everything.)

I have a python script that looks like this:

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

Then, if I try:

result=mything(4,5)

then result correctly contains the values of all the attributes first assigned to it via thingfromsoftware but result.dimensions has not been assigned (has no attribute "dimensions")

The goal is to store the dimensions of every result computed and configured by myfunctionthing in some semi-coherent manner.

Real code (upon request)

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)


You're doing

tube=io.read(str(name))

if

TYPE!='bare'

So in that case you wouldn't get the dimensions. Could this be why you're having the problem?

Also, have you tried just doing

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

instead of setattr? It's only needed when the name of the attribute to change is stored in a variable name.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号