评估类返回false

Rac*_*l W 2 python class shapely

我写过这堂课:

class DSMCalc(object):
    def __init__(self, footprint):
        if footprint.__class__.__base__.__module__ is not 'shapely.geometry.base':
            raise TypeError('footprint input geometry is not a shapely geometry based object')
        self.footprint = footprint
Run Code Online (Sandbox Code Playgroud)

作为最好的,我可以告诉我需要做的全业务__class__.__base__.__module__,因为我想是包括所有匀称的对象(shapely.geometry.polygon.Polygon和shapely.geometry.multipolygon.MultiPolygon,例如)和属性组合是我发现,好像这是可行的,因为所有的对象我想包括输出shapely.geometry.base.

但是,当我运行代码时,即使放入有效shapely.geometry.polygon.Polygon对象,我也会收到TypeError .我已经尝试了上面的代码shapely.geometry.base作为字符串和模块.怎么会这样?

一些示例对象重现错误:

valid_geojson_polygon_feature = {
'properties': {"name":"test"},
'type': 'Feature',
'geometry': {
    'coordinates': [[(-122.4103173469268, 37.78337247419125), (-122.41042064203376, 37.7833590750075),
                     (-122.41046641056752, 37.78360478527359), (-122.41047393562782, 37.783644775039576),
                     (-122.4103759761863, 37.78365638609612), (-122.4103173469268, 37.78337247419125)]],
    'type': 'Polygon'}}

from shapely.geometry import shape as get_shape
valid_shapely_polygon_feature = get_shape(valid_geojson_polygon_feature['geometry'])
print(valid_shapely_polygon_feature.__class__.__base__.__module__)
DSMCalc(valid_shapely_polygon_feature)
Run Code Online (Sandbox Code Playgroud)

Sha*_*ger 5

您不能依赖于is使用字符串文字.即使它工作,它也是CPython的一个实现细节,在这种情况下,即使CPython的实现也不支持它,因为CPython只会自动插入符合标识符规则的字符串文字(即变量名).你的字符串包含.s,这意味着它不会自动实现.您可以在交互式提示中轻松查看:

>>> x = 'shapely.geometry.base'  # Not a legal variable name
>>> y = 'shapely.geometry.base'
>>> x is y
False
>>> x = 'abc123'  # Legal variable name
>>> y = 'abc123'
>>> x is y
True
Run Code Online (Sandbox Code Playgroud)

基本上,将测试更改为!= 'shapely.geometry.base',如果您需要更多详细信息,请阅读和之间的区别is==.

我会注意到你的测试在其他方面存在缺陷.现在,您需要定义直接父级shapely.geometry.base.但是如果你继承了一个有效的类,那么子将是无效的(因为__base__它将引用另一个模块的子类,而不是最终的基类shapely.geometry.base).更好的解决方案是isinstance根据已知的良好基类进行适当的检查,例如:

# Top of file
from shapely.geometry.base import BaseGeometry, GeometrySequence

# Test code (passing a tuple of legal bases classes is allowed)
if not isinstance(footprint, (BaseGeometry, GeometrySequence)):
    raise TypeError('footprint input geometry is not a shapely geometry based object')
Run Code Online (Sandbox Code Playgroud)

其中,上更加明确,你希望(明确列举的法律基础班),并允许有问题的类的间接子类,而不是只有基类的该模块的屈指可数的直接子类,避免让什么顶级虚假类型,如CAP_STYLE和JOIN_STYLE(虽然在定义中shapely.geometry.base,似乎主要存在于简单的类似枚举的常量类中,而不是与实际几何相关的东西,并且可能不是您想要允许的类型).