使用RxPY进行说明。
我想从函数创建一个observable,但该函数必须带参数。这个特定的例子必须以随机的间隔返回我想发送给它的许多预定义的代码之一。到目前为止,我的解决方案是使用闭包:
from __future__ import print_function
from rx import Observable
import random
import string
import time
def make_tickers(n = 300, s = 123):
""" generates up to n unique 3-letter strings geach makde up of uppsercase letters"""
random.seed(s)
tickers = [''.join(random.choice(string.ascii_uppercase) for _ in range(3)) for y in range(n)]
tickers = list(set(tickers)) # unique
print(len(tickers))
return(tickers)
def spawn_prices_fn(tickers):
""" returns a function that will return a random element
out of tickers every 20-100 ms, and takes an observable parameter """
def spawner(observer):
while True:
next_tick = random.choice(tickers)
observer.on_next(next_tick)
time.sleep(random.randint(20, 100)/1000.0)
return(spawner)
if __name__ == "__main__":
spawned = spawn_prices_fn(make_tickers())
xx = Observable.create(spawned)
xx.subscribe(lambda s: print(s))
有更简单的方法吗?可以将其他参数发送到Observable.create的第一个参数函数,它不需要闭包吗?什么是规范建议?
答案 0 :(得分:1)
它可以通过多种方式完成,这里的解决方案之一并没有太多改变您的代码。
请注意,代码生成也可以分解为一个函数,生成一个字符串,结合一些<?php
/*
Woocommerce plugin details
*/
if (!defined('ABSPATH')) {
exit;
// Exit if accessed directly
}
/**
* Check if WooCommerce is active
**/
if (in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins')))) {
function my_shipping_method()
{
if (!class_exists('my_shipping_method')) {
class my_shipping_method extends WC_Shipping_Method
{
/**
* Constructor for the shipping class
*
* @access public
* @return void
*/
public function __construct()
{
$this->id = 'my_shipping_method';
$this->method_title = __('Custom Ondemand Shipping', 'my_shipping_method');
$this->method_description = __('Custom Shipping Method for Custom Ondemand', 'my_shipping_method');
// Availability & Countries
$this->availability = 'including';
$this->countries = array('KE');
$this->init();
$this->enabled = isset($this->settings['enabled']) ? $this->settings['enabled'] : 'yes';
$this->title = isset($this->settings['title']) ? $this->settings['title'] : __('Custom Ondemand Shipping', 'my_shipping_method');
$this->API_username = isset($this->settings['API_username']) ? $this->settings['API_username'] : 'myusername';
$this->API_key = isset($this->settings['API_key']) ? $this->settings['API_key'] : 'mykey';
$this->CUSTOM_LIVE_URL = 'https://api.custom.com/v1';
$this->CUSTOM_TEST_URL = 'https://apitest.custom.com/v1/';
$this->CUSTOM_URL = (isset($this->settingd['USE_LIVE_API']) && $this->settingd['USE_LIVE_API'] == 'yes' )? $this->CUSTOM_LIVE_URL : $this->CUSTOM_TEST_URL;
}
/**
* Init the settings
*
* @access public
* @return void
*/
function init()
{
// Load the settings API
$this->init_form_fields();
$this->init_settings();
// Save settings in admin if you have any defined
add_action('woocommerce_update_options_shipping_' . $this->id, array($this, 'process_admin_options'));
//register google maps places library
wp_register_script('mapsPlaces', 'https://maps.googleapis.com/maps/api/js?key=' . $this->settings['maps_API_key'] . '&libraries=places', array(), false);
wp_register_style('main_style', plugins_url('css/my_shipping_method-woocommerce.css', __FILE__));
wp_enqueue_style('main_style');
}
/**
* Define settings field for this shipping
* @return void
*/
function init_form_fields()
{
$this->form_fields = array(
'enabled' => array(
'title' => __('Enable', 'my_shipping_method'),
'type' => 'checkbox',
'description' => __('Enable this shipping method.', 'my_shipping_method'),
'default' => 'yes'
),
'USE_LIVE_API' => array(
'title' => __('Use Live API', 'my_shipping_method'),
'type' => 'checkbox',
'description' => __('Check if you want to use the live API or uncheck to use the test API.', 'my_shipping_method'),
'default' => 'yes'
),
'title' => array(
'title' => __('Title', 'my_shipping_method'),
'type' => 'text',
'description' => __('Title displayed to users', 'my_shipping_method'),
'default' => __('Custom Ondemand', 'my_shipping_method')
),
'API_username' => array(
'title' => __('Custom Ondemand username', 'my_shipping_method'),
'type' => 'text',
'description' => __('Custom Ondemand merchant username. You can signup here <a href="http://custom.com">http://custom.com</a>', 'my_shipping_method'),
'default' => __('myusername', 'my_shipping_method')
),
'API_key' => array(
'title' => __('Custom Ondemand API key', 'my_shipping_method'),
'type' => 'text',
'description' => __('Custom Ondemand merchant API key. You can find it in your Custom Ondemand merchant profile', 'my_shipping_method'),
'default' => __('mykey', 'my_shipping_method')
),
'maps_API_key' => array(
'title' => __('Maps API key', 'my_shipping_method'),
'type' => 'text',
'description' => __('Google maps API key. You can find it Go to the <a href="https://console.developers.google.com/project/_/apiui/apis/enabled">Google API Console</a>' .
'Click the Select a project button, then select the same project you set up for the Google Maps JavaScript API and click Open.' .
'From the list of APIs on the Dashboard, look for Google Places API Web Service.' .
'If you see the API in the list, you are all set. If the API is not listed, enable it:' .
'At the top of the page, select ENABLE API to display the Library tab. Alternatively, from the left side menu, select Library.' .
'Search for Google Places API Web Service, then select it from the results list.' .
'Select ENABLE. When the process finishes, Google Places API Web Service appears in the list of APIs on the Dashboard.'
, 'my_shipping_method'),
'default' => __('mapskey', 'my_shipping_method')
),
);
}
/**
* This function is used to calculate the shipping cost. Within this function we can check for weights, dimensions and other parameters.
*
* @access public
* @param mixed $package
* @return void
*/
public function calculate_shipping($package = Array())
{
$cost = 150;
$weight = 0;
parse_str($_POST['post_data'], $order_data);
$to_name = "";
$to_lat = "";
$to_long = "";
$recepient_name = "";
$recepient_phone = "";
$recepient_email = "";
if ($order_data['ship_to_different_address']) {
$to_name = $order_data['shipping_address_1'];
$to_lat = $order_data['shipping_lat'];
$to_long = $order_data['shipping_lng'];
$recepient_name = $order_data['shipping_first_name'] . " " . $order_data['shipping_last_name'];
$recepient_phone = isset($order_data['shipping_phone']) ? $order_data['shipping_phone'] : $order_data['billing_phone'];
$recepient_email = isset($order_data['shipping_email']) ? $order_data['shipping_email'] : $order_data['billing_email'];
} else {
$to_name = $order_data['billing_address_1'];
$to_lat = $order_data['billing_lat'];
$to_long = $order_data['billing_lng'];
$recepient_name = $order_data['billing_first_name'] . " " . $order_data['billing_last_name'];
$recepient_phone = $order_data['billing_phone'];
$recepient_email = $order_data['billing_email'];
}
foreach ($package['contents'] as $item_id => $values) {
$_product = $values['data'];
if ($_product->has_weight()) {
$weight = $weight + $_product->weight() * $values['quantity'];
}
}
$api_username = $this->settings['API_username'];
$api_key = $this->settings['API_key'];
$data = '';//data passed to the api. Tested to be okay.
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL =>$this->CUSTOM_URL,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => $data,
CURLOPT_HTTPHEADER => array(
"cache-control: no-cache",
"content-type: application/json"
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
$cost = 200;
} else {
// echo $response;
$result = json_decode($response, true);
$cost = $result['data']['amount'];
}
$rate = array(
'id' => $this->id,
'label' => $this->title,
'cost' => $cost
);
$this->add_rate($rate);
}
}
}
}
add_action('woocommerce_shipping_init', 'my_shipping_method');
function add_my_shipping_method($methods)
{
$methods['my_shipping_method'] = 'my_shipping_method';
return $methods;
}
add_filter('woocommerce_shipping_methods', 'add_my_shipping_method');
function my_shipping_method_validate_order($posted)
{
$packages = WC()->shipping->get_packages();
$chosen_methods = WC()->session->get('chosen_shipping_methods');
if (is_array($chosen_methods) && in_array('my_shipping_method', $chosen_methods)) {
foreach ($packages as $i => $package) {
if ($chosen_methods[$i] != "my_shipping_method") {
continue;
}
$my_shipping_method = new my_shipping_method();
$weight = 0;
foreach ($package['contents'] as $item_id => $values) {
$_product = $values['data'];
if ($_product->has_weight()) {
$weight = $weight + $_product->weight * $values['quantity'];
}
}
$weight = wc_get_weight($weight, 'kg');
}
}
}
// add_action('woocommerce_review_order_before_cart_contents', 'my_shipping_method_validate_order', 10);
// add_action('woocommerce_after_checkout_validation', 'my_shipping_method_validate_order', 10);
// Hook in
add_filter('woocommerce_checkout_fields', 'my_shipping_method_override_checkout_fields');
// Our hooked in function - $fields is passed via the filter!
function my_shipping_method_override_checkout_fields($fields)
{
// load the autocomplete script
wp_enqueue_script('my_shipping_method-woocommerce', plugin_dir_url(__FILE__) . 'js/my_shipping_method-woocommerce.js', array('mapsPlaces'));
$fields['shipping']['shipping_lat'] = array(
'label' => __('Latitude', 'my_shipping_method'),
'placeholder' => _x('Lat', 'placeholder', 'my_shipping_method'),
'required' => true,
'class' => array('form-row-first', 'placesAutoComplete', 'hidden'),
'label_class' => array('hidden'),
'clear' => true
);
$fields['shipping']['shipping_lng'] = array(
'label' => __('Longitude', 'my_shipping_method'),
'placeholder' => _x('long', 'placeholder', 'my_shipping_method'),
'required' => true,
'class' => array('form-row-last', 'placesAutoComplete', 'hidden'),
'label_class' => array('hidden'),
'clear' => true
);
$fields['billing']['billing_lat'] = array(
'label' => __('Latitude', 'my_shipping_method'),
'placeholder' => _x('Lat', 'placeholder', 'my_shipping_method'),
'required' => true,
'class' => array('form-row-first', 'placesAutoComplete', 'hidden'),
'label_class' => array('hidden'),
'clear' => true
);
$fields['billing']['billing_lng'] = array(
'label' => __('Longitude', 'my_shipping_method'),
'placeholder' => _x('long', 'placeholder', 'my_shipping_method'),
'required' => true,
'class' => array('form-row-last', 'placesAutoComplete', 'hidden'),
'label_class' => array('hidden'),
'clear' => true
);
return $fields;
}
/**
* Display field value on the order edit page
*/
add_action('woocommerce_admin_order_data_after_shipping_address', 'my_shipping_method_custom_checkout_field_display_admin_order_meta', 10, 1);
function my_shipping_method_custom_checkout_field_display_admin_order_meta($order)
{
echo '<p><strong>' . __('Delivery location') . ':</strong> ' . get_post_meta($order->get_id(), '_shipping_location', true) . '</p>';
}
/**
* Process the checkout
*/
add_action('woocommerce_checkout_process', 'location_checkout_field_process');
function location_checkout_field_process()
{
// // Check if set, if its not set add an error.
// if (!$_POST['shipping_location'] && !$_POST['billing_location'])
// wc_add_notice(__('Please enter a biling location.'), 'error');
//
// }
// FORCE SHIPPING COST RECALCULATION
WC()->cart->calculate_shipping();
WC()->cart->calculate_totals();
}
}
魔法更多 array.reverse()
- 就像
我还稍微调整了代码以使rx
满意
rx
或没有flake8
的解决方案:
from __future__ import print_function
import random
import string
import time
from rx import Observable
def make_tickers(n=300, s=123):
"""
Generates up to n unique 3-letter strings each made up of uppercase letters
"""
random.seed(s)
tickers = [''.join(random.choice(string.ascii_uppercase) for _ in range(3))
for y in range(n)]
tickers = list(set(tickers)) # unique
print(len(tickers))
return(tickers)
def random_picker(tickers):
ticker = random.choice(tickers)
time.sleep(random.randint(20, 100) / 1000.0)
return ticker
if __name__ == "__main__":
xx = Observable\
.repeat(make_tickers())\
.map(random_picker)\
.subscribe(lambda s: print(s))
make_tickers
可以从from __future__ import print_function
import random
import string
import time
from rx import Observable
def random_picker(tickers):
ticker = random.choice(tickers)
time.sleep(random.randint(20, 100) / 1000.0)
return ticker
if __name__ == "__main__":
random.seed(123)
Observable.range(1, 300)\
.map(lambda _: ''.join(random.choice(string.ascii_uppercase)
for _ in range(3)))\
.reduce(lambda x, y: x + [y], [])\
.do_while(lambda _: True)\
.map(random_picker)\
.subscribe(lambda s: print(s))
移开,但代码会变得有点棘手
答案 1 :(得分:0)
您还可以使用“partials”来包装您的订阅方法。它允许您定义其他参数,但在仅等待 Observer 和 Scheduler 的方法上调用 rx.create:
res.status(400).json({ message: `There is user with email ${email}` });
return;