我写了这个课:
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.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)
答案 0 :(得分:5)
您不能依靠is
处理字符串文字。即使有效,它也是CPython的实现细节,在这种情况下,即使CPython的实现也不支持它,因为CPython只会自动插入适合标识符(即变量名)规则的字符串文字。您的字符串包含.
,这意味着它不会自动被阻止。您可以在交互式提示下轻松看到这一点:
>>> 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
中的最终基类)。更好的解决方案是根据已知的良好基类进行适当的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')
,除了更明确地说明您想要的内容(明确列举合法的基类),并允许所涉及类的间接子类,而不是仅允许该模块中少数基类的直接子类之外,还避免了虚假的情况像CAP_STYLE
和JOIN_STYLE
这样的类型(虽然在shapely.geometry.base
中定义,但似乎主要以类似于枚举的常量类存在,而不是与几何相关的实际事物存在,并且可能不是您所键入的类型要允许)。