K8s通过reflect实现多态

 

转子:https://www.jianshu.com/p/4d8c4db86943

关于reflect包使用可以参考:https://www.cnblogs.com/ksir16/p/9040656.html

我们知道在golang中可以把函数赋值给一个变量,然后通过函数名调用函数。

下面的问题是我们如何实现callFunc()的内容来完成所要的功能呢。

目前已知的办法好像是不行的,无法从全局域中通过名字获取一个函数的对象。
(对于变量也一样,无法从全局域中通过名字获取一个变量的对象)

可行的办法

使用一个map变量显式的把字符串和函数(变量)关联起来:

这样我们可以通过funcs["foo"]得到函数对象,然后才能对函数进行操作。

函数操作的例子

下面是一个函数调用的例子,包括参数的传递以及返回值的处理。

package main
import "fmt"
import "reflect"
import "errors"

type MyStruct struct{
	i int
	s string
}
func foo0() int {
	fmt.Println("running foo0:")
	return 100
}
func foo1(a int)(string,string) {
	fmt.Println("running foo1: ",a)
	return "aaa","bbb"
}
func foo2(a,b int,c string) MyStruct {
	fmt.Println("running foo2: ",a,b,c)
	return MyStruct{10,"ccc"}
}

func MyCall(m map[string]interface{},name string, params ... interface{})(result []reflect.Value,err error){
	f :=reflect.ValueOf(m[name]) //获得函数对象
	if  len(params) != f.Type().NumIn() {
		err = errors.New("The number of params is not adapted.")
		return
	}
	//处理参数
	in :=make([]reflect.Value, len(params))
	for k,param := range params {
		in[k] = reflect.ValueOf(param)
	}
	result = f.Call(in)
	return
}

func main() {
	funcs := map[string]interface{} {
		"foo0": foo0,
		"foo1": foo1,
		"foo2": foo2,
	}
	//call foo0
	if result,err := MyCall(funcs,"foo0");err ==nil{
		for _, r :=range result {
			fmt.Printf(" return: type=%v, value=[%s]\n",r.Type(),r.Int())
		}
	}
	// call foo1
	if result, err := MyCall(funcs,"foo1",1);err == nil {
		for _,r := range result {
			fmt.Printf("return: type=%v, value=[%s]\n",r.Type(),r.String())
		}
	}
	// 
     if result, err := MyCall(funcs, "foo2", 1, 2, "aa"); err == nil { 
		 for _, r := range result { 
			 fmt.Printf(" return: type=%v, value=[%+v]\n", r.Type(), r.Interface().(MyStruct)) 
			}
	 } 
}

还是补充一点吧:

其中Type是interface类型,Value是struct类型,意识到这一点很重要

Value

Value为go值提供了反射接口。

不是所有go类型值的Value表示都能使用所有方法。请参见每个方法的文档获取使用限制。在调用有分类限定的方法时,应先使用Kind方法获知该值的分类。调用该分类不支持的方法会导致运行时的panic。

Value类型的零值表示不持有某个值。零值的IsValid方法返回false,其Kind方法返回Invalid,而String方法返回<invalid Value>,所有其它方法都会panic。绝大多数函数和方法都永远不返回Value零值。如果某个函数/方法返回了非法的Value,它的文档必须显式的说明具体情况。

如果某个go类型值可以安全的用于多线程并发操作,它的Value表示也可以安全的用于并发。

获取Value对象的方法:

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数据增强是指通过对原始数据进行一系列变换,生成新的数据来增加数据量,提高模型的泛化能力和鲁棒性。其中加噪声是一种常用的数据增强方法,可以增加数据的多样性,减少过拟合。 在Python中,可以通过以下方式实现加噪声的数据增强: 1. 添加高斯噪声 ```python import numpy as np def add_gaussian_noise(image, mean=0, std=0.1): noise = np.random.normal(mean, std, image.shape) noisy_image = image + noise return np.clip(noisy_image, 0, 1) ``` 其中,`mean`和`std`分别表示高斯噪声的均值和标准差,`np.random.normal`函数用于生成符合高斯分布的随机数,`np.clip`函数用于将像素值限制在[0, 1]之间。 2. 添加椒盐噪声 ```python def add_salt_pepper_noise(image, prob=0.05): noisy_image = np.copy(image) salt = np.random.binomial(1, prob, image.shape[:2]) pepper = np.random.binomial(1, prob, image.shape[:2]) noisy_image[salt == 1] = 1 noisy_image[pepper == 1] = 0 return noisy_image ``` 其中,`prob`表示椒盐噪声的概率,`np.random.binomial`函数用于生成伯努利分布的随机数,`1`表示概率为`prob`的事件发生,`0`表示概率为`1-prob`的事件发生。 3. 添加随机旋转、平移、缩放等变换 ```python from keras.preprocessing.image import ImageDataGenerator def random_transform(image, seed=None): datagen = ImageDataGenerator( rotation_range=20, width_shift_range=0.1, height_shift_range=0.1, shear_range=0.2, zoom_range=0.2, horizontal_flip=True, fill_mode='reflect', data_format='channels_last', ) return datagen.random_transform(image, seed=seed) ``` 其中,`rotation_range`表示旋转角度范围,`width_shift_range`和`height_shift_range`表示平移范围,`shear_range`表示剪切范围,`zoom_range`表示缩放范围,`horizontal_flip`表示是否进行水平翻转,`fill_mode`表示边缘像素填充方式。 以上三种方法可以根据具体场景和需求进行组合使用,实现数据增强加噪声。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值