我正在编写一个脚本,让我连接到Sentinel卫星数据库以下载请求的地图文件。
from sentinelsat import SentinelAPI, read_geojson, geojson_to_wkt
def get_available(input_geojson, user, password, date_start, date_end, satellite, sensormode, product_type):
# LogIn
api = SentinelAPI(user, password , 'https://scihub.copernicus.eu/dhus')
# Input parameter of the search
footprint = geojson_to_wkt(read_geojson(input_geojson)) # irrelevant to the question
products = api.query(footprint,
date = (date_start, date_end),
platformname = satellite,
sensoroperationalmode = sensormode,
producttype = product_type,
)
我的问题取决于我将使用哪种“卫星”输入,它将改变哪些其他参数是必需的,必需的甚至允许的。一些不需要“ sensormode”,而另一些则需要“ cloudcoverage”。如何在函数内的函数中编写带有变量/可选参数的干净代码?我必须列出所有可能的论点吗?
答案 0 :(得分:1)
该API似乎太乏味了,无法使用。最好将参数与类分组。
from sentinelsat import SentinelAPI, read_geojson, geojson_to_wkt
class Satellite:
def __init__(self, name, producttype, sensormode=None, cloudcoverage=None):
self.name = name
self.producttype = producttype
self.sensormode = sensormode
self.cloudcoverage = cloudcoverage
class SentinelConnection:
def __init__(self, input_geojson, user, password):
self.input_geojson = input_geojson
self.user = user
self.password = password
self.api = None
self.footprint = None
def __enter__(self):
self.api = SentinelAPI(self.user, self.password,
'https://scihub.copernicus.eu/dhus')
self.footprint = geojson_to_wkt(read_geojson(self.input_geojson))
def __exit__(self, exc_type, exc_val, exc_tb):
# logout here
pass
def get_available(conn, satellite, date_start, date_end):
s = satellite
products = conn.api.query(conn.footprint,
date=(date_start, date_end),
platformname=satellite,
sensoroperationalmode=s.sensormode,
producttype=s.product_type,
)
def main():
with SentinelConnection("abc.json", "name", "password") as conn:
satellite = Satellite('Sputnik X', 'military satellite')
get_available(conn, satellite, date_start, date_end)
对于足迹,我一无所知。如果不同的查询可以使用不同的足迹,并且查询经常重复使用相同的足迹,则为足迹创建一个Location类。
答案 1 :(得分:1)
我发现“抓取周期”的答案非常Python化且美观,因此我建议您继续使用。无论如何,我在这方面的工作很有趣,所以这是我对您要寻找的内容的解释:)
@RunWith(PowerMockRunner.class)
@PrepareForTest(ExampleClass.class)
public class ExampleClassTest {
private final ExampleClass exampleClass = new ExampleClass();
@Test
public void exceptionIsNotThrownIfCoolObjHasNoErrors() throws Exception {
CoolObj coolObjMock = Mockito.mock(CoolObj.class);
PowerMockito.whenNew(CoolObj.class).withNoArguments().thenReturn(coolObjMock);
Mockito.when(coolObjMock.hasErrors()).thenReturn(false);
Assertions.assertThatCode(exampleClass::doSomething)
.doesNotThrowAnyException();
}
@Test
public void exceptionIsThrownIfCoolObjHasErrors() throws Exception {
CoolObj coolObjMock = Mockito.mock(CoolObj.class);
PowerMockito.whenNew(CoolObj.class).withNoArguments().thenReturn(coolObjMock);
Mockito.when(coolObjMock.hasErrors()).thenReturn(true);
Assertions.assertThatThrownBy(exampleClass::doSomething)
.isInstanceOf(RuntimeException.class);
}
}
有一些约束使此实现保持简洁:
答案 2 :(得分:0)
我相信这可以通过* kwargs很好地解决。这使您可以将任何键盘参数传递给函数,而无需在函数签名中指定,即:
def foobar(foo, **kwargs):
bar = kwargs["bar"]
return foo + bar
barfoo = foobar(foo='something', bar='other_thing')