子类化ctypes-Python [英] Subclassing ctypes - Python

查看:51
本文介绍了子类化ctypes-Python的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我在互联网上找到的一些代码。我不确定该如何使用。我只是用枚举键/值填充了 members ,并且它起作用了,但是我很好奇这个元类的全部含义。我假设它与ctypes有关,但是我找不到关于ctypes子类化的很多信息。我知道EnumerationType并没有使用我使用Enumeration的方式。

This is some code I found on the internet. I'm not sure how it is meant to be used. I simply filled members with the enum keys/values and it works, but I'm curious what this metaclass is all about. I am assuming it has something to do with ctypes, but I can't find much information on subclassing ctypes. I know EnumerationType isn't doing anything the way I'm using Enumeration.

from ctypes import *

class EnumerationType(type(c_uint)):  
    def __new__(metacls, name, bases, dict):  
        if not "_members_" in dict:  
            _members_ = {}  
            for key,value in dict.items():  
                if not key.startswith("_"):  
                    _members_[key] = value  
            dict["_members_"] = _members_  
        cls = type(c_uint).__new__(metacls, name, bases, dict)  
        for key,value in cls._members_.items():  
            globals()[key] = value  
        return cls  

    def __contains__(self, value):
        return value in self._members_.values()

    def __repr__(self):
        return "<Enumeration %s>" % self.__name__

class Enumeration(c_uint):
    __metaclass__ = EnumerationType
    _members_ = {}
    def __init__(self, value):
        for k,v in self._members_.items():
            if v == value:
                self.name = k
                break
        else:
            raise ValueError("No enumeration member with value %r" % value)
        c_uint.__init__(self, value)


    @classmethod
    def from_param(cls, param):
        if isinstance(param, Enumeration):
            if param.__class__ != cls:
                raise ValueError("Cannot mix enumeration members")
            else:
                return param
        else:
            return cls(param)

    def __repr__(self):
        return "<member %s=%d of %r>" % (self.name, self.value, self.__class__)

And an enumeration probably done the wrong way.  

class TOKEN(Enumeration):
    _members_ = {'T_UNDEF':0, 'T_NAME':1, 'T_NUMBER':2, 'T_STRING':3, 'T_OPERATOR':4, 'T_VARIABLE':5, 'T_FUNCTION':6}


推荐答案

元类是用于创建类的类。这样想:所有对象都有一个类,一个类也是一个对象,因此,一个类可以具有一个类是有意义的。

A metaclass is a class used to create classes. Think of it this way: all objects have a class, a class is also an object, therefore, it makes sense that a class can have a class.

http://www.ibm.com/developerworks/linux/library/l-pymeta .html

要了解其作用,您可以查看代码中的几点。

To understand what this is doing, you can look at a few points in the code.

 _members_ = {'T_UNDEF':0, 'T_NAME':1, 'T_NUMBER':2, 'T_STRING':3, 'T_OPERATOR':4, 'T_VARIABLE':5, 'T_FUNCTION':6}

globals()[key] = value

这里需要使用字典中定义的每个键: T_UNDEF和 T_NUMBER,并使其在您的全局字典中可用。

Here it takes every defined key in your dictionary: "T_UNDEF" "T_NUMBER" and makes them available in your globals dictionary.

def __init__(self, value):
    for k,v in self._members_.items():
        if v == value:
            self.name = k
            break

无论何时创建枚举实例,它将在初始化类时检查值是否在允许的枚举名称列表中。找到值时,它将字符串名称设置为self.name。

Whenever you make an instance of your enum, it will check to see if the "value" is in your list of allowable enum names when you initialized the class. When the value is found, it sets the string name to self.name.

c_uint.__init__(self, value)

这是将 ctypes值设置为实际的c无符号整数的实际行。

This is the actual line which sets the "ctypes value" to an actual c unsigned integer.

这篇关于子类化ctypes-Python的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆