' MyClass的'对象没有属性' __ getitem __'

时间:2015-08-04 10:43:10

标签: python

我有一个类似这样的课程:

import android.app.Activity;
import android.hardware.Camera;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Environment;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import java.io.File;
import java.io.IOException;

public class MainActivity extends Activity implements SurfaceHolder.Callback {

    private static final String LOG_TAG = MainActivity.class.getCanonicalName();
    Button myButton;
    MediaRecorder mediaRecorder;
    SurfaceHolder surfaceHolder;
    boolean recording;
    private TextView mTimer;
    private Camera mCamera;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        recording = false;
        mediaRecorder = new MediaRecorder();
        mCamera = Camera.open();
        initMediaRecorder();

        SurfaceView myVideoView = (SurfaceView) findViewById(R.id.videoview);
        surfaceHolder = myVideoView.getHolder();
        surfaceHolder.addCallback(this);

        myButton = (Button) findViewById(R.id.mybutton);
        myButton.setOnClickListener(myButtonOnClickListener);

        mTimer = (TextView) findViewById(R.id.timer);
    }

    private Button.OnClickListener myButtonOnClickListener
            = new Button.OnClickListener() {

        @Override
        public void onClick(final View arg0) {
            CountDownTimer countDownTimer = new CountDownTimer(90 * 1000, 1000) {
                @Override
                public void onTick(long millisUntilFinished) {
                    mTimer.setText(String.valueOf(millisUntilFinished / 1000));
                }

                @Override
                public void onFinish() {
                    onClick(arg0);
                }
            };

            if (recording) {
                // Stop recording and finish
                try {
                    mediaRecorder.stop();
                    mediaRecorder.reset();
                    mediaRecorder.release();
                    finish();
                } catch (Exception e) {
                    Log.e(LOG_TAG, "Failed to stop recorder", e);
                }

            } else {
                // Release the camera and start recording
                mCamera.release();
                countDownTimer.start();
                mediaRecorder.start();
                recording = true;
                myButton.setText("STOP");
            }
        }
    };


    @Override
    public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {

    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        if (mCamera != null) {
            Camera.Parameters params = mCamera.getParameters();
            mCamera.setParameters(params);
            try {
                mCamera.setPreviewDisplay(holder);
            } catch (IOException e) {
                e.printStackTrace();
            }
            mCamera.startPreview();
        }
        prepareMediaRecorder();
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder arg0) {

    }

    private void initMediaRecorder() {
        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
        mediaRecorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
        CamcorderProfile camcorderProfile_HQ = CamcorderProfile.get(CamcorderProfile.QUALITY_CIF);
        mediaRecorder.setProfile(camcorderProfile_HQ);
        File file = new File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), "myvideo.mp4");
        if (file.exists()) {
            file.delete();
        }
        mediaRecorder.setOutputFile(file.getAbsolutePath());
        mediaRecorder.setMaxDuration(90000); // Set max duration 90 sec.
        mediaRecorder.setMaxFileSize(15000000); // Set max file size 15M
    }

    private void prepareMediaRecorder() {
        mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());

        try {
            mediaRecorder.prepare();
        } catch (IllegalStateException | IOException e) {
            Log.e(LOG_TAG, "Failed to prepare recorder", e);
        }
    }
}

在我的主代码中,我创建了一个名为class MyClass(object): def __init__(self, id, a, b, c): self.myList = [] self.id = id self.a = a self.b = b self.c = c def addData(self, data): self.myList.append(data) 的MyClass实例列表。在一行中,我必须检查具有给定myClassList的项目是否已存在。我是这样做的:

id

该代码中的第二行给出了此错误:

  

' MyClass的'对象没有属性id = 'foo' # in real code is set dynamically recent_item = next( (item for item in myClassList if item['id'] == id), None )

我该如何解决?

5 个答案:

答案 0 :(得分:22)

item不是字典而是类,因此它具有不同的语法来访问成员。以这种方式访问​​id

item.id

答案 1 :(得分:14)

如果您确实希望能够使用inst["attr"]访问您的属性并解释错误,则需要向您的班级添加__getitem__

class MyClass(object):
    def __init__(self, id, a, b, c):
        self.myList     = []
        self.id         = id
        self.a          = a
        self.b          = b
        self.c          = c

    def addData(self, data):
        self.myList.append(data)

    def __getitem__(self, item):
        return getattr(self, item)

答案 2 :(得分:2)

id是MyClass实例的属性,您必须以item.id

的形式访问它
recent_item = next( (item for item in myClassList if item.id == id), None )

答案 3 :(得分:1)

与错误建议一样,如果类定义了__getitem__()实例方法,则只能在类实例上使用下标。

由于id是实例的属性,您应该使用 - item.id代替item['id']

示例 -

recent_item = next( (item for item in myClassList if item.id == id), None )

答案 4 :(得分:0)

正如其他人所指出的,您可以简单地使用

public class MessagingServicesConfigTest {
    private MessagingServicesConfig config;
    private EMSJMSConfig emsJmsConfig;
    @BeforeMethod
    public void setUp() throws Exception {
        config = new MessagingServicesConfig();
        ... //what needs to be done here to have the EMSJMSConfig
    }
    @Test
    public void testBuildsCorrectService() throws JMSException {
        MessagingService service = config.messagingService();   
        ...
    }
}

但是,如果要动态访问字段,有时确实需要使用以下语法:

item.id

在这种情况下,您可以按照Anand的建议使用__getitem __()语法,但是对__getitem__使用python的包装器会更安全:

item[dynamicField]