评价 class returns false

Evaluation of class returns false

我写了这个class:

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

据我所知,我需要完成 __class__.__base__.__module__ 的全部工作,因为我试图包含所有形状的对象(例如 shapely.geometry.polygon.Polygonshapely.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)

您不能依赖 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

基本上,将测试更改为 != 'shapely.geometry.base',如果您需要更多详细信息,请继续阅读 the difference between is and ==

我会注意到您的测试在其他方面存在缺陷。现在,您需要在 shapely.geometry.base 中定义直接 parent。但是如果你 subclass 一个有效的 class,child 将是无效的(因为 __base__ 将引用来自其他模块的 subclass,而不是shapely.geometry.base 中的最终基数 class)。更好的解决方案是根据已知的良好基础 class 进行适当的 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')

其中,除了更明确地说明您想要什么(明确列举法律基础 classes),并允许间接子 classes 的 classes 有问题而不是仅来自该模块的少数基础 classes 的直接子 classes,避免允许像 CAP_STYLEJOIN_STYLE 这样的虚假类型(虽然定义在 shapely.geometry.base,似乎主要作为简单的 enum-like classes 常量存在,而不是与实际几何相关的东西,并且可能不是您想要允许的类型)。