我遇到一种情况,需要获取对封闭的匿名内部类的引用:
我有一些异步方法from __future__ import print_function
import keras
from keras.datasets import mnist
from keras.layers import Dense, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras.models import Sequential
import matplotlib.pylab as plt
batch_size = 128
num_classes = 10
epochs = 10
# input image dimensions
img_x, img_y = 28, 28
# load the MNIST data set, which already splits into train and test sets for us
(x_train, y_train), (x_test, y_test) = mnist.load_data()
# reshape the data into a 4D tensor - (sample_number, x_img_size, y_img_size, num_channels)
# because the MNIST is greyscale, we only have a single channel - RGB colour images would have 3
x_train = x_train.reshape(x_train.shape[0], img_x, img_y, 1)
x_test = x_test.reshape(x_test.shape[0], img_x, img_y, 1)
input_shape = (img_x, img_y, 1)
# convert the data to the right type
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255
print('x_train shape:', x_train.shape)
print(x_train.shape[0], 'train samples')
print(x_test.shape[0], 'test samples')
# convert class vectors to binary class matrices - this is for use in the
# categorical_crossentropy loss below
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)
model = Sequential()
model.add(Conv2D(32, kernel_size=(5, 5), strides=(1, 1),
activation='relu',
input_shape=input_shape))
model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))
model.add(Conv2D(64, (5, 5), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dense(1000, activation='relu'))
model.add(Dense(num_classes, activation='softmax'))
model.compile(loss=keras.losses.categorical_crossentropy,
optimizer=keras.optimizers.Adam(),
metrics=['accuracy'])
class AccuracyHistory(keras.callbacks.Callback):
def on_train_begin(self, logs={}):
self.acc = []
def on_epoch_end(self, batch, logs={}):
self.acc.append(logs.get('acc'))
history = AccuracyHistory()
model.fit(x_train, y_train,
batch_size=batch_size,
epochs=epochs,
verbose=1,
validation_data=(x_test, y_test),
callbacks=[history])
score = model.evaluate(x_test, y_test, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])
plt.plot(range(1, 11), history.acc)
plt.xlabel('Epochs')
plt.ylabel('Accuracy')
plt.show()
,它在完成后会调用结果回调(由库提供给我;无法更改),而我正在尝试编写一个自动重试的结果回调如果doSomething(...)
失败了几次,方法是将doSomething(...)
发布到消息队列中,该消息队列将在100毫秒的重试延迟后执行。
由于该调用需要再次传递相同的结果回调,因此我需要从Runnable
的运行方法中获取对我的结果回调的引用,如下所示:
Runnable
使用此interface ResultListener {
public void onSuccess();
public void onFailure();
}
private static void doSomething(ResultListener listener) {
// Do something fun here...
}
public static void main(String[] args) throws IOException {
final ResultListener autoRetry = new ResultListener() {
@Override
public void onSuccess() {
// Yay! Everything works!
}
@Override
public void onFailure() {
final ResultListener outerThis = this; // This can't be necessary!
// Schedule retry in 100ms
messageThread.postDelayed(new Runnable() {
@Override
public void run() {
doSomething(outerThis); // What else could I do here?
}
}, 100);
}
};
doSomething(autoRetry);
}
-hack是唯一的方法吗?看起来真的很笨拙。以下无效:
outerThis
-返回this
的实例,而不是匿名Runnable
ResultListener
(我本来应该工作的)抛出ResultListener.this
No enclosing instance of the type ResultListener is accessible in scope
抛出autoRetry
很明显,我可以通过定义一个The local variable autoRetry may not have been initialized
类来命名匿名类,然后我将其实例化并使用RetryListener
,但这似乎又没有必要... < / p>
我想念什么吗?