这是我的解决方案,如果有人有更好的请评论或更正。在
创意:
其想法是,每个类都可以有一个特定属性的别名列表,这样用户就可以(基于类名逻辑:>;point需要x、y、z、name属性、dog需要品种、名称、年龄、性别属性等等)根据自己的内部逻辑调用属性,而无需确切知道sed attribute具有什么属性。在
逻辑:
如果函数或类有一些关键字参数可供输入,那么我将需要与sed参数相关联的最小常用词列表。同义词和习语可以很容易地在google上搜索,但是我建议不要使用大的同义词列表,保持较小的2-3+属性名。然后我们只需要将这些别名映射到原始属性,因为我们作为代码需要知道如何在不调用getattr(self,someattributestring)的情况下调用属性
代码:
我们必须首先定义一个函数来生成别名。在# generate aliases for attributes
def generateAliases(*argListNames):
returningValues = [] # this could be omitted if user wants to make generator
la = returningValues.append # this could be omitted also
#dominated argListNames
argListNames = map( str, argListNames ) #for simplicity convert to strings
argListNames = map( str.lower , argListNames ) #for simplicity convert to lower string
argListNames = list(argListNames) # back to list
# small nameless lambda functions
getFirstChr = lambda element: element[0] # getting first character
conectedJoing= lambda connector,item,args: connecter.join([ item, args if not __isTL__(args) else connecter.join(args) ]) # generating joined string
# list of string convertors used to generate aliases
convertorList= [ lambda x: x , getFirstChr , str.title , str.upper , lambda x: getFirstChr( str.upper(x) ) ]
for item in argListNames:
## since we dont want alias to repeat itself
listNoitem = filter( lambda x: x!=item , argListNames )
listNoitem = list(listNoitem)
la(item) # if returningValues omitted use yield statement
for conversion in convertorList: ##1 keeping up with for loops
converted = conversion(item)
for connecter in "_,".split(","):
for listItem in listNoitem:
for cnvrt in convertorList: ##2 cnvrt is converted second stage : used to convert the whole list of items without current alias
cList = cnvrt(listItem)
la( conectedJoing(connecter,converted,cList) )# if returningValues omitted use yield statement
la( conectedJoing(connecter,converted,listNoitem) )# if returningValues omitted use yield statement
# if user wanted to make generator omit next lines
returningValues = [ x.replace("_","") if x.endswith("_") else x for x in returningValues ]
returningValues = sorted(set(returningValues))
return list( map(str,returningValues) )
现在我们需要映射并检查函数或类中的参数,因此我们需要一些参数解析器。在
^{pr2}$
实施def somefunction(**kwargs):
aliases = {
"val1":generateAliases("first","1"),
"val2":generateAliases("second","2")
}
aproved = argumentParser(aliases,**kwargs)
if "val1" in aproved.keys(): val1 = aproved["val1"]
else: val1 = 0 # seting default value for val1
if "val2" in aproved.keys(): val2 = aproved["val2"]
else: val2 = 1 # seting default value for val2
#do something or your code here
return val1,val2
# for testing purposes
for x in [ {"first":1} , {"second":2,"first":3} , {"f1":4,"s2":5} , {"f_1":6,"2_s":7} ]:
# displaying imputed variables
form = ["passed "]
form += [ "{} as {} ".format(key,value) for key,value in x.items() ]
# implementing somefunciton
print( "".join(form), somefunction(**x) )
输出python27 -m kwtest
Process started >>>
passed first as 1 (1, 1)
passed second as 2 first as 3 (3, 2)
passed f1 as 4 s2 as 5 (4, 5)
passed 2_s as 7 f_1 as 6 (6, 7)
<<< Process finished. (Exit code 0)
python35 -m kwtest
Process started >>>
passed first as 1 (1, 1)
passed first as 3 second as 2 (3, 2)
passed f1 as 4 s2 as 5 (4, 5)
passed f_1 as 6 2_s as 7 (6, 7)
<<< Process finished. (Exit code 0)
如果在类中实现,这个过程在__init__中是相似的,但是__getitem__、__setitem__和{}必须进行编码,这样它们才能在别名中搜索属性名称。属性名也可以用self.attributes = list( aliases.keys())或类似的方法生成那个。违约值可以存储在具有__kwdefaults__或“默认值”的类中,具体取决于函数使用的数据类型。在
如您所见,这段代码已经在py2.7和py3.5上进行了测试。在
如有需要,请进一步解释
您可以在类全局属性或__init__中定义别名。
进一步解释__getitem__:def __getitem__(self,item):
if item in self.aliases.keys():
return getattr(self,item)
if any( item in value for value in self.aliases.values() ):
item = [ key for key in self.aliases.keys() if item in self.aliases[key] ] [0]
return getattr(self,item)
if item in range( len( self.aliases.keys() ) ):
item = list( self.aliases.keys() )[item]
return getattr(self,item)
进一步解释__setitem__:def __setitem__(self,item,value):
item = self.__getitem__(self,item)
#? must have `__dict__` method or class needs to be instanced from object like class someclass(object)
item = [ key for key in vars(self).items() if self[key] == item] [0]
if item != None:
setattr(self,item,value)