我写过这门课:

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对象(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中定义直接父级。但是,如果对有效类进行子类划分,则子类将无效(因为__base__将引用来自另一个模块的子类,而不是shapely.geometry.base中的最终基类)。一个更好的解决方案是基于已知的良好基类进行适当的检查,例如:
# 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')

在更明确地说明您想要的(明确枚举合法基类)的情况下,允许所讨论的类的间接子类而不是仅从该模块中的几个基类的直接子类,避免了像isinstanceCAP_STYLE之类的伪类型(在JOIN_STYLE中定义的)似乎存在很大。像枚举一样简单的常量类,不是实际的几何相关的东西,很可能不是您想要允许的类型)。

10-04 12:25