[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/laomagege/pythonnet/develop/src/runtime/pyobject.cs [Back]  [Original]

// ==========================================================================
// This software is subject to the provisions of the Zope Public License,
// Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
// FOR A PARTICULAR PURPOSE.
// ==========================================================================

using System;

namespace Python.Runtime {

    /// 
    /// Represents a generic Python object. The methods of this class are 
    /// generally equivalent to the Python "abstract object API". See  
    /// http://www.python.org/doc/current/api/object.html for details.
    /// 

    public class PyObject : IDisposable {

    protected internal IntPtr obj = IntPtr.Zero;
    private bool disposed = false;

    /// 
    /// PyObject Constructor
    /// 
    ///
    /// 
    /// Creates a new PyObject from an IntPtr object reference. Note that
    /// the PyObject instance assumes ownership of the object reference 
    /// and the reference will be DECREFed when the PyObject is garbage 
    /// collected or explicitly disposed.
    /// 

    public PyObject(IntPtr ptr) {
        obj = ptr;
    }

    // Protected default constructor to allow subclasses to manage
    // initialization in different ways as appropriate.

    protected PyObject() {}

    // Ensure that encapsulated Python object is decref'ed appropriately
    // when the managed wrapper is garbage-collected.

    ~PyObject() {
        Dispose();
    }


    /// 
    /// Handle Property
    /// 
    ///
    /// 
    /// Gets the native handle of the underlying Python object. This
    /// value is generally for internal use by the PythonNet runtime. 
    /// 

    public IntPtr Handle {
        get { return obj; }
    }


    /// 
    /// FromManagedObject Method
    /// 
    ///
    /// 
    /// Given an arbitrary managed object, return a Python instance that
    /// reflects the managed object.
    /// 

    public static PyObject FromManagedObject(object ob) {
        // Special case: if ob is null, we return None.
        if (ob == null) {
            Runtime.Incref(Runtime.PyNone);
            return new PyObject(Runtime.PyNone);
        }
        IntPtr op = CLRObject.GetInstHandle(ob);
        return new PyObject(op);
    }


    /// 
    /// AsManagedObject Method
    /// 
    ///
    /// 
    /// Return a managed object of the given type, based on the 
    /// value of the Python object.
    /// 

    public object AsManagedObject(Type t) {
        Object result;
        if (!Converter.ToManaged(this.Handle, t, out result, false)) {
            throw new InvalidCastException("cannot convert object to target type");
        }
        return result;
    }


    /// 
    /// Dispose Method
    /// 
    ///
    /// 
    /// The Dispose method provides a way to explicitly release the 
    /// Python object represented by a PyObject instance. It is a good
    /// idea to call Dispose on PyObjects that wrap resources that are 
    /// limited or need strict lifetime control. Otherwise, references 
    /// to Python objects will not be released until a managed garbage 
    /// collection occurs.
    /// 

    public void Dispose() {
        if (!disposed) {
            if (Runtime.Py_IsInitialized() > 0) {
                IntPtr gs = PythonEngine.AcquireLock();
                Runtime.Decref(obj);
                obj = IntPtr.Zero;    
                PythonEngine.ReleaseLock(gs);
            }
            GC.SuppressFinalize(this);
            disposed = true;
        }
    }


    /// 
    /// GetPythonType Method
    /// 
    ///
    /// 
    /// Returns the Python type of the object. This method is equivalent
    /// to the Python expression: type(object).
    /// 

    public PyObject GetPythonType() {
        IntPtr tp = Runtime.PyObject_Type(obj);
        return new PyObject(tp);
    }


    /// 
    /// TypeCheck Method
    /// 
    ///
    /// 
    /// Returns true if the object o is of type typeOrClass or a subtype 
    /// of typeOrClass.
    /// 

    public bool TypeCheck(PyObject typeOrClass) {
        return Runtime.PyObject_TypeCheck(obj, typeOrClass.obj);
    }


    /// 
    /// HasAttr Method
    /// 
    ///
    /// 
    /// Returns true if the object has an attribute with the given name.
    /// 

    public bool HasAttr(string name) {
        return (Runtime.PyObject_HasAttrString(obj, name) != 0);
    }


    /// 
    /// HasAttr Method
    /// 
    ///
    /// 
    /// Returns true if the object has an attribute with the given name,
    /// where name is a PyObject wrapping a string or unicode object.
    /// 

    public bool HasAttr(PyObject name) {
        return (Runtime.PyObject_HasAttr(obj, name.obj) != 0);
    }


    /// 
    /// GetAttr Method
    /// 
    ///
    /// 
    /// Returns the named attribute of the Python object, or raises a 
    /// PythonException if the attribute access fails.
    /// 

    public PyObject GetAttr(string name) {
        IntPtr op = Runtime.PyObject_GetAttrString(obj, name);
        if (op == IntPtr.Zero) {
            throw new PythonException();
        }
        return new PyObject(op);
    }


    /// 
    /// GetAttr Method
    /// 
    ///
    /// 
    /// Returns the named attribute of the Python object, or the given
    /// default object if the attribute access fails.
    /// 

    public PyObject GetAttr(string name, PyObject _default) {
        IntPtr op = Runtime.PyObject_GetAttrString(obj, name);
        if (op == IntPtr.Zero) {
            Runtime.PyErr_Clear();
            return _default;
        }
        return new PyObject(op);
    }


    /// 
    /// GetAttr Method
    /// 
    ///
    /// 
    /// Returns the named attribute of the Python object or raises a 
    /// PythonException if the attribute access fails. The name argument 
    /// is a PyObject wrapping a Python string or unicode object.
    /// 

    public PyObject GetAttr(PyObject name) {
        IntPtr op = Runtime.PyObject_GetAttr(obj, name.obj);
        if (op == IntPtr.Zero) {
            throw new PythonException();
        }
        return new PyObject(op);
    }


    /// 
    /// GetAttr Method
    /// 
    ///
    /// 
    /// Returns the named attribute of the Python object, or the given
    /// default object if the attribute access fails. The name argument 
    /// is a PyObject wrapping a Python string or unicode object.
    /// 

    public PyObject GetAttr(PyObject name, PyObject _default) {
        IntPtr op = Runtime.PyObject_GetAttr(obj, name.obj);
        if (op == IntPtr.Zero) {
            Runtime.PyErr_Clear();
            return _default;
        }
        return new PyObject(op);
    }


    /// 
    /// SetAttr Method
    /// 
    ///
    /// 
    /// Set an attribute of the object with the given name and value. This
    /// method throws a PythonException if the attribute set fails.
    /// 

    public void SetAttr(string name, PyObject value) {
        int r = Runtime.PyObject_SetAttrString(obj, name, value.obj);
        if (r < 0) {
            throw new PythonException();
        }
    }


    /// 
    /// SetAttr Method
    /// 
    ///
    /// 
    /// Set an attribute of the object with the given name and value, 
    /// where the name is a Python string or unicode object. This method
    /// throws a PythonException if the attribute set fails.
    /// 

    public void SetAttr(PyObject name, PyObject value) {
        int r = Runtime.PyObject_SetAttr(obj, name.obj, value.obj);
        if (r < 0) {
            throw new PythonException();
        }
    }


    /// 
    /// DelAttr Method
    /// 
    ///
    /// 
    /// Delete the named attribute of the Python object. This method
    /// throws a PythonException if the attribute set fails.
    /// 

    public void DelAttr(string name) {
        int r = Runtime.PyObject_SetAttrString(obj, name, IntPtr.Zero);
        if (r < 0) {
            throw new PythonException();
        }
    }


    /// 
    /// DelAttr Method
    /// 
    ///
    /// 
    /// Delete the named attribute of the Python object, where name is a 
    /// PyObject wrapping a Python string or unicode object. This method 
    /// throws a PythonException if the attribute set fails.
    /// 

    public void DelAttr(PyObject name) {
        int r = Runtime.PyObject_SetAttr(obj, name.obj, IntPtr.Zero);
        if (r < 0) {
            throw new PythonException();
        }
    }


    /// 
    /// GetItem Method
    /// 
    ///
    /// 
    /// For objects that support the Python sequence or mapping protocols,
    /// return the item at the given object index. This method raises a 
    /// PythonException if the indexing operation fails.
    /// 

    public virtual PyObject GetItem(PyObject key) {
        IntPtr op = Runtime.PyObject_GetItem(obj, key.obj);
        if (op == IntPtr.Zero) {
            throw new PythonException();
        }
        return new PyObject(op);
    }


    /// 
    /// GetItem Method
    /// 
    ///
    /// 
    /// For objects that support the Python sequence or mapping protocols,
    /// return the item at the given string index. This method raises a 
    /// PythonException if the indexing operation fails.
    /// 

    public virtual PyObject GetItem(string key) {
        return GetItem(new PyString(key));
    }


    /// 
    /// GetItem Method
    /// 
    ///
    /// 
    /// For objects that support the Python sequence or mapping protocols,
    /// return the item at the given numeric index. This method raises a 
    /// PythonException if the indexing operation fails.
    /// 

    public virtual PyObject GetItem(int index) {
        PyInt key = new PyInt(index);
        return GetItem((PyObject)key);
    }


    /// 
    /// SetItem Method
    /// 
    ///
    /// 
    /// For objects that support the Python sequence or mapping protocols,
    /// set the item at the given object index to the given value. This 
    /// method raises a PythonException if the set operation fails.
    /// 

    public virtual void SetItem(PyObject key, PyObject value) {
        int r = Runtime.PyObject_SetItem(obj, key.obj, value.obj);
        if (r < 0) {
            throw new PythonException();
        }
    }


    /// 
    /// SetItem Method
    /// 
    ///
    /// 
    /// For objects that support the Python sequence or mapping protocols,
    /// set the item at the given string index to the given value. This 
    /// method raises a PythonException if the set operation fails.
    /// 

    public virtual void SetItem(string key, PyObject value) {
        SetItem(new PyString(key), value);
    }


    /// 
    /// SetItem Method
    /// 
    ///
    /// 
    /// For objects that support the Python sequence or mapping protocols,
    /// set the item at the given numeric index to the given value. This 
    /// method raises a PythonException if the set operation fails.
    /// 

    public virtual void SetItem(int index, PyObject value) {
        SetItem(new PyInt(index), value);
    }


    /// 
    /// DelItem Method
    /// 
    ///
    /// 
    /// For objects that support the Python sequence or mapping protocols,
    /// delete the item at the given object index. This method raises a 
    /// PythonException if the delete operation fails.
    /// 

    public virtual void DelItem(PyObject key) {
        int r = Runtime.PyObject_DelItem(obj, key.obj);
        if (r < 0) {
            throw new PythonException();
        }
    }


    /// 
    /// DelItem Method
    /// 
    ///
    /// 
    /// For objects that support the Python sequence or mapping protocols,
    /// delete the item at the given string index. This method raises a 
    /// PythonException if the delete operation fails.
    /// 

    public virtual void DelItem(string key) {
        DelItem(new PyString(key));
    }


    /// 
    /// DelItem Method
    /// 
    ///
    /// 
    /// For objects that support the Python sequence or mapping protocols,
    /// delete the item at the given numeric index. This method raises a 
    /// PythonException if the delete operation fails.
    /// 

    public virtual void DelItem(int index) {
        DelItem(new PyInt(index));
    }


    /// 
    /// Length Method
    /// 
    ///
    /// 
    /// Returns the length for objects that support the Python sequence 
    /// protocol, or 0 if the object does not support the protocol.
    /// 

    public virtual int Length() {
        int s = Runtime.PyObject_Size(obj);
        if (s < 0) {
            Runtime.PyErr_Clear();
            return 0;
        }
        return s;
    }


    /// 
    /// String Indexer
    /// 
    ///
    /// 
    /// Provides a shorthand for the string versions of the GetItem and 
    /// SetItem methods.
    /// 

    public virtual PyObject this[string key] {
        get { return GetItem(key); }
        set { SetItem(key, value); }
    }


    /// 
    /// PyObject Indexer
    /// 
    ///
    /// 
    /// Provides a shorthand for the object versions of the GetItem and 
    /// SetItem methods.
    /// 

    public virtual PyObject this[PyObject key] {
        get { return GetItem(key); }
        set { SetItem(key, value); }
    }


    /// 
    /// Numeric Indexer
    /// 
    ///
    /// 
    /// Provides a shorthand for the numeric versions of the GetItem and 
    /// SetItem methods.
    /// 

    public virtual PyObject this[int index] {
        get { return GetItem(index); }
        set { SetItem(index, value); }
    }


    /// 
    /// GetIterator Method
    /// 
    ///
    /// 
    /// Return a new (Python) iterator for the object. This is equivalent
    /// to the Python expression "iter(object)". A PythonException will be 
    /// raised if the object cannot be iterated.
    /// 

    public PyObject GetIterator() {
        IntPtr r = Runtime.PyObject_GetIter(obj);
        if (r == IntPtr.Zero) {
            throw new PythonException();
        }
        return new PyObject(r);
    }


    /// 
    /// Invoke Method
    /// 
    ///
    /// 
    /// Invoke the callable object with the given arguments, passed as a
    /// PyObject[]. A PythonException is raised if the invokation fails.
    /// 

    public PyObject Invoke(params PyObject[] args) {
        PyTuple t = new PyTuple(args);
        IntPtr r = Runtime.PyObject_Call(obj, t.obj, IntPtr.Zero);
        t.Dispose();
        if (r == IntPtr.Zero) {
            throw new PythonException();
        }
        return new PyObject(r);
    }


    /// 
    /// Invoke Method
    /// 
    ///
    /// 
    /// Invoke the callable object with the given arguments, passed as a
    /// Python tuple. A PythonException is raised if the invokation fails.
    /// 

    public PyObject Invoke(PyTuple args) {
        IntPtr r = Runtime.PyObject_Call(obj, args.obj, IntPtr.Zero);
        if (r == IntPtr.Zero) {
            throw new PythonException();
        }
        return new PyObject(r);
    }


    /// 
    /// Invoke Method
    /// 
    ///
    /// 
    /// Invoke the callable object with the given positional and keyword
    /// arguments. A PythonException is raised if the invokation fails.
    /// 

    public PyObject Invoke(PyObject[] args, PyDict kw) {
        PyTuple t = new PyTuple(args);
        IntPtr r = Runtime.PyObject_Call(obj, t.obj, kw.obj);
        t.Dispose();
        if (r == IntPtr.Zero) {
            throw new PythonException();
        }
        return new PyObject(r);
    }


    /// 
    /// Invoke Method
    /// 
    ///
    /// 
    /// Invoke the callable object with the given positional and keyword
    /// arguments. A PythonException is raised if the invokation fails.
    /// 

    public PyObject Invoke(PyTuple args, PyDict kw) {
        IntPtr r = Runtime.PyObject_Call(obj, args.obj, kw.obj);
        if (r == IntPtr.Zero) {
            throw new PythonException();
        }
        return new PyObject(r);
    }


    /// 
    /// InvokeMethod Method
    /// 
    ///
    /// 
    /// Invoke the named method of the object with the given arguments.
    /// A PythonException is raised if the invokation is unsuccessful.
    /// 

    public PyObject InvokeMethod(string name, params PyObject[] args) {
        PyObject method = GetAttr(name);
        PyObject result = method.Invoke(args);
        method.Dispose();
        return result;
    }


    /// 
    /// InvokeMethod Method
    /// 
    ///
    /// 
    /// Invoke the named method of the object with the given arguments.
    /// A PythonException is raised if the invokation is unsuccessful.
    /// 

    public PyObject InvokeMethod(string name, PyTuple args) {
        PyObject method = GetAttr(name);
        PyObject result = method.Invoke(args);
        method.Dispose();
        return result;
    }


    /// 
    /// InvokeMethod Method
    /// 
    ///
    /// 
    /// Invoke the named method of the object with the given arguments 
    /// and keyword arguments. Keyword args are passed as a PyDict object.
    /// A PythonException is raised if the invokation is unsuccessful.
    /// 

    public PyObject InvokeMethod(string name, PyObject[] args, PyDict kw) {
        PyObject method = GetAttr(name);
        PyObject result = method.Invoke(args, kw);
        method.Dispose();
        return result;
    }


    /// 
    /// InvokeMethod Method
    /// 
    ///
    /// 
    /// Invoke the named method of the object with the given arguments 
    /// and keyword arguments. Keyword args are passed as a PyDict object.
    /// A PythonException is raised if the invokation is unsuccessful.
    /// 

    public PyObject InvokeMethod(string name, PyTuple args, PyDict kw) {
        PyObject method = GetAttr(name);
        PyObject result = method.Invoke(args, kw);
        method.Dispose();
        return result;
    }


    /// 
    /// IsInstance Method
    /// 
    ///
    /// 
    /// Return true if the object is an instance of the given Python type
    /// or class. This method always succeeds.
    /// 

    public bool IsInstance(PyObject typeOrClass) {
        int r = Runtime.PyObject_IsInstance(obj, typeOrClass.obj);
        if (r < 0) {
            Runtime.PyErr_Clear();
            return false;
        }
        return (r != 0);
    }


    /// 
    /// IsSubclass Method
    /// 
    ///
    /// 
    /// Return true if the object is identical to or derived from the 
    /// given Python type or class. This method always succeeds.
    /// 

    public bool IsSubclass(PyObject typeOrClass) {
        int r = Runtime.PyObject_IsSubclass(obj, typeOrClass.obj);
        if (r < 0) {
            Runtime.PyErr_Clear();
            return false;
        }
        return (r != 0);
    }


    /// 
    /// IsCallable Method
    /// 
    ///
    /// 
    /// Returns true if the object is a callable object. This method 
    /// always succeeds.
    /// 

    public bool IsCallable() {
        return (Runtime.PyCallable_Check(obj) != 0);
    }


    /// 
    /// IsTrue Method
    /// 
    ///
    /// 
    /// Return true if the object is true according to Python semantics.
    /// This method always succeeds.
    /// 

    public bool IsTrue() {
        return (Runtime.PyObject_IsTrue(obj) != 0);
    }


    /// 
    /// Dir Method
    /// 
    ///
    /// 
    /// Return a list of the names of the attributes of the object. This
    /// is equivalent to the Python expression "dir(object)".
    /// 

    public PyList Dir() {
        IntPtr r = Runtime.PyObject_Dir(obj);
        if (r == IntPtr.Zero) {
            throw new PythonException();
        }
        return new PyList(r);
    }


    /// 
    /// Repr Method
    /// 
    ///
    /// 
    /// Return a string representation of the object. This method is 
    /// the managed equivalent of the Python expression "repr(object)".
    /// 

    public string Repr() {
        IntPtr strval = Runtime.PyObject_Repr(obj);
        string result = Runtime.GetManagedString(strval);
        Runtime.Decref(strval);
        return result;
    }


    /// 
    /// ToString Method
    /// 
    ///
    /// 
    /// Return the string representation of the object. This method is 
    /// the managed equivalent of the Python expression "str(object)".
    /// 

    public override string ToString() {
        IntPtr strval = Runtime.PyObject_Unicode(obj);
        string result = Runtime.GetManagedString(strval);
        Runtime.Decref(strval);
        return result;
    }


    /// 
    /// Equals Method
    /// 
    ///
    /// 
    /// Return true if this object is equal to the given object. This
    /// method is based on Python equality semantics.
    /// 

    public override bool Equals(object o) {
        if (!(o is PyObject)) {
            return false;
        }
        if (obj == ((PyObject) o).obj) {
            return true;
        }
        int r = Runtime.PyObject_Compare(obj, ((PyObject) o).obj);
        if (Exceptions.ErrorOccurred()) {
            throw new PythonException();
        }
        return (r == 0);
    }


    /// 
    /// GetHashCode Method
    /// 
    ///
    /// 
    /// Return a hashcode based on the Python object. This returns the
    /// hash as computed by Python, equivalent to the Python expression
    /// "hash(obj)".
    /// 

    public override int GetHashCode() {
        return Runtime.PyObject_Hash(obj).ToInt32();
    }


    }


}

Web Proxy Viewer  |  New URL  |  Original Page