简体   繁体   English

检查变量是否属于python中的类

[英]Checking if a variable belongs to a class in python

I have a small class which is as follows :我有一个小班如下:

class Gender(object):
    MALE = 'M'
    FEMALE = 'F'

I have a parameter variable which can be only M or F .To ensure it is only that, I do the following :我有一个只能是MF的参数变量。为确保仅此而已,我执行以下操作:

>>> parameter = 'M'
>>> if parameter not in (Gender.MALE, Gender.FEMALE)
...     print "Invalid parameter"
...
Invalid parameter
>>>

Now I have a class which contains all the States in USA as follows:现在我有一个包含美国所有州的类,如下所示:

class States(object):
    ALABAMA = 'AL'
    ALASKA = 'AK'
    ARIZONA = 'AZ'
    ARKANSAS = 'AR'
    CALIFORNIA = 'CA'
    COLORADO = 'CO'
    CONNECTICUT = 'CT'
    DELAWARE = 'DE'
    DISTRICTOFCOLUMBIA = 'DC'
    ....
....

Like the example above,my parameter now is AL .However, since there are 50 states in the USA,I cannot practically use the tuple with 50 variables like I used above.Is there a better way of doing this ?像上面的例子一样,我的参数现在是AL 。但是,由于美国有 50 个州,我实际上不能像上面使用的那样使用具有 50 个变量的元组。有没有更好的方法来做到这一点? I did read about isinstance but it did not give me the expected results.我确实读过 isinstance ,但它没有给我预期的结果。

You could use the __dict__ property which composes a class, for example:您可以使用组成类的__dict__属性,例如:

In [1]: class Foo(object):
   ...:     bar = "b"
   ...:     zulu = "z"
   ...:     
In [2]: "bar"  in Foo.__dict__
Out[2]: True

Or as you're searching for the values use __dict__.values() :或者在您搜索值时使用__dict__.values()

In [3]: "b" in Foo.__dict__.values()
Out[3]: True

As Peter Wood points out, the vars() built-in can also be used to retrieve the __dict__ :正如 Peter Wood 指出的那样,内置的vars()也可用于检索__dict__

In [12]: "b" in vars(Foo).values()
Out[12]: True

The __dict__ property is used as a namespace for classes and so will return all methods, magic methods and private properties on the class as well, so for robustness you might want to modify your search slightly to compensate. __dict__属性用作命名空间,因此也会返回该类的所有方法、魔术方法和私有属性,因此为了健壮性,您可能需要稍微修改搜索以进行补偿。

In your case, you might want to use a classmethod , such as:在您的情况下,您可能想要使用classmethod ,例如:

class States(object):
    ALABAMA = "AL"
    FLORIDA = "FL"

    @classmethod
    def is_state(cls, to_find):
        print(vars(cls))
        states = [val for key, val in vars(cls).items()
                  if not key.startswith("__")
                  and isinstance(val, str)]
        return to_find in states

States.is_state("AL") # True
States.is_state("FL") # True
States.is_state("is_state") # False
States.is_state("__module__") # False

Update This clearly answer's the OPs question, but readers may also be interested in the Enum library in Python 3, which would quite possibly be a better container for data such as this.更新这清楚地回答了 OPs 问题,但读者可能也对 Python 3 中的Enum库感兴趣,它很可能是此类数据的更好容器。

Why don't you use a dictionary?你为什么不用字典? Its a lot simpler and lookups will be easier as well.它更简单,查找也会更容易。

states = {'AL': 'Alabama', 'AK': 'Alaska' ... }
test_state = 'Foo'

if test_state not in states.keys():
    print('{} is not valid input'.format(test_state))

I would suggest using Enum to define both Gender and States .我建议使用 Enum 来定义GenderStates
Enum if part of the standard library on Python 3 .枚举如果是Python 3标准库的一部分。 If you are on Python 2 use enum34 , install with pip install enum34 .如果您使用的是Python 2使用enum34 ,请使用pip install enum34

from enum import Enum
class States(Enum):
    ALABAMA = 'AL'
    ALASKA = 'AK'
    ARIZONA = 'AZ'
    ARKANSAS = 'AR'
    CALIFORNIA = 'CA'
    COLORADO = 'CO'
    CONNECTICUT = 'CT'
    DELAWARE = 'DE'
    DISTRICTOFCOLUMBIA = 'DC'
    ...

Then you can check if a variable is one of the states by然后你可以检查一个变量是否是状态之一

isinstance(variable, States)

Indeed if you can set at the beginning all your arguments it is better just to put the required arguments without default arguments.实际上,如果您可以在开头设置所有参数,那么最好只放置所需的参数而不使用默认参数。 This forces the user to set the arguments.这会强制用户设置参数。 However, often you might want to set the attributes later for various reasons.但是,由于各种原因,您通常可能希望稍后设置属性。

I find very handy to define a class Required that I can use as a place holder, and use a function validate before the object "is sent to production".我发现定义一个我可以用作占位符的类 Required 非常方便,并在对象“发送到生产”之前使用函数validate

class Required(object):
    def __init__(self,description=None):
        self.description = description
    def __repr__(self): 
        return 'Required attribute:%s' %self.description



class MyClass(object):
    def __init__(self):
        self.ID = Required(self.ID = Required("ID is mandatory, please set it using set_ID method."))
        self.context = None
        self.type = "MyClass"


    def set_ID(self,MyClass_ID):
        """
        The id property identifies this MyClass with the URL at which it is available online.
        """
        # check MyClass_ID is valid before assigning it
        # valid(ID)
        self.ID = MyClass_ID

    def validate(self):
        for i in self.__dict__.values():
            if isinstance(i, Required):
                print(i)
                # Warining or raise error

g = MyClass()
g.validate()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM