In Python:
在Python中:
a = "l[0], l[1], l[2], l[3]"
# l[0] etc. have their own value
my_function(a) #doesn't work
#but this does work
my_function(l[0], l[1], l[2], l[3])
Can the string a be 'transformed' so that the function sees the variables? Thank you.
字符串a可以“转换”,以便函数看到变量吗?谢谢。
Later update: Thank you for answering my question. I am including the bigger problem and why I had to resort to the eval function (not desired according to your answers). The function:
稍后更新:感谢您回答我的问题。我包括更大的问题以及为什么我不得不求助于eval函数(根据你的答案不合适)。功能:
class Line(object):
def __init__(self, pt1, pt2, *pt):
pt1 = Point(pt1[0],pt1[1])
pt2 = Point(pt2[0],pt2[1])
self.vertices = [pt1, pt2]
for i in pt:
self.vertices.append(Point(i[0],i[1]))
def __getitem__(self, key):
pt = self.vertices[key]
p = Point(p[0],p[1])
return p
#Here is the part with the issue:
def move(self, dx, dy):
pts = len(self.vertices)
l = self.vertices
pt1 = Point(Point(l[0].x, l[0].y).move(dx, dy).x, Point(l[0].x, l[0].y).move(dx, dy).y)
pt2 = Point(Point(l[1].x, l[1].y).move(dx, dy).x, Point(l[1].x, l[1].y).move(dx, dy).y)
if pts == 2:
mv = LineString(p1, p2)
if pts > 2:
bla = ''
for i in [2,pts]:
px = Point(l[i].x, l[i].y).move(dx, dy).x
py = Point(l[i].x, l[i].y).move(dx, dy).y
l[i] = Point(px,py)
bla += 'l[' + str(i) + '], '
arguments = bla[:-2]
mv = LineString(pt1, pt2, *eval(arguments))
return mv
According to your answers, there are better ways of solving this..
根据你的答案,有更好的方法来解决这个问题。
3 个解决方案
#1
3
To do this, you can combine the eval
function to evaluate the string with the *
operator to apply my_function
on the resulting tuple:
为此,您可以组合eval函数以使用*运算符计算字符串,以在生成的元组上应用my_function:
my_function(*eval(a))
However, doing this without a very good reason is almost always an indication of bad design. eval
makes your code vulnerable to run-time errors and code injection attacks, and removes important performance optimizations. If you describe your actual requirements, it is likely that someone can propose a better solution.
然而,没有很好的理由这样做几乎总是表明设计不好。 eval使您的代码容易受到运行时错误和代码注入攻击的影响,并消除了重要的性能优化。如果您描述实际需求,可能有人可以提出更好的解决方案。
#2
3
You had an XY problem.
Your real X problem was to pass an arbitrary number of objects to a function.
After having defined a string containing the identifiers of these objects, the Y solution to extract back the objects from this string became your graal.
But I'm pretty sure that the following snippet answers to your real X problem:
你有一个XY问题。你真正的X问题是将任意数量的对象传递给一个函数。在定义了包含这些对象的标识符的字符串之后,从该字符串中提取回对象的Y解决方案成为了您的平等对象。但我很确定以下代码片段可以解答您的真实X问题:
if pts > 2:
blal = []
for i in [2,pts]:
px = Point(l[i].x, l[i].y).move(dx, dy).x
py = Point(l[i].x, l[i].y).move(dx, dy).y
blal.append(Point(px,py))
mv = LineString(pt1, pt2, *blal)
It's a facility offered by Python to pass arbitrary number of arguments to a function, not present in all programming languages. Would be a pity to complicate one's life , not using it.
它是Python提供的一种工具,可以将任意数量的参数传递给函数,而不是所有编程语言都存在。将一个人的生活复杂化而不是使用它会是一种遗憾。
I think that new members should be informed, or even prevented, not to upvote and accept answers too rapidly.
我认为新成员应该被告知,甚至被阻止,不要过快地投票和接受答案。
EDIT
I think that you can replace the code block in your question with this one:
我认为你可以用这个替换你问题中的代码块:
from itertools import chain
class Line(object):
def __init__(self, pt1, pt2, *pt):
self.vertices = map(lambda x: Point(*x),
chain((pt1,pt2), pt))
def __getitem__(self, key):
return Point(*self.vertices[key])
def move(self, dx, dy):
return LineString(*[ Point(Point(v.x, v.y).move(dx, dy).x,
Point(v.x, v.y).move(dx, dy).y)
for v in self.vertices])
You could even define Point()
in such a way that it would accept a couple (tuple, list... , I dont't know what your pt
s are) instead of elements of pt
So, you could write Point(x)
instead of Point(*x)
and
你甚至可以用这样的方式定义Point(),它会接受一对(元组,列表......,我不知道你的pts是什么)而不是pt的元素所以你可以写Point(x)代替Point(* x)和
self.vertices = map(Point, chain((pt1,pt2), pt))
instead of
代替
self.vertices = map(lambda x: Point(*x),
chain((pt1,pt2), pt))
but would need to write Point((v.x,v.y))
instead of Point(v.x,v.y)
但需要写Point((v.x,v.y))而不是Point(v.x,v.y)
#3
2
Python methods take arbitrary argument lists. What this means is that your function can take any number of arguments.
Python方法采用任意参数列表。这意味着你的函数可以使用任意数量的参数。
Here is an example:
这是一个例子:
def foo(*args, **kwargs):
print args
foo('a','b','c','d')
Now, suppose you wanted to pass a list with values in it as arguments:
现在,假设您想要将包含值的列表作为参数传递:
mylist = ['a','b','c','d']
foo(mylist)
Now this will result in:
现在这将导致:
(['a', 'b', 'c', 'd'],)
A tuple with your list as the first argument. What we want is the same affect as foo('a','b','c','d')
. To get that, we need to expand the list, like this:
以列表作为第一个参数的元组。我们想要的是与foo相同的影响('a','b','c','d')。为此,我们需要扩展列表,如下所示:
foo(*mylist)
Now you'll get the same result:
现在你会得到相同的结果:
('a', 'b', 'c', 'd')
Taking this and applying it to your problem:
考虑到这一点并将其应用于您的问题:
def foo(*args, **kwargs):
print "Total arguments: {}".format(len(args))
v = "a, b, c"
>>> foo(v)
Total arguments: 1
>>> foo(*v.split(','))
Total arguments: 3
#1
3
To do this, you can combine the eval
function to evaluate the string with the *
operator to apply my_function
on the resulting tuple:
为此,您可以组合eval函数以使用*运算符计算字符串,以在生成的元组上应用my_function:
my_function(*eval(a))
However, doing this without a very good reason is almost always an indication of bad design. eval
makes your code vulnerable to run-time errors and code injection attacks, and removes important performance optimizations. If you describe your actual requirements, it is likely that someone can propose a better solution.
然而,没有很好的理由这样做几乎总是表明设计不好。 eval使您的代码容易受到运行时错误和代码注入攻击的影响,并消除了重要的性能优化。如果您描述实际需求,可能有人可以提出更好的解决方案。
#2
3
You had an XY problem.
Your real X problem was to pass an arbitrary number of objects to a function.
After having defined a string containing the identifiers of these objects, the Y solution to extract back the objects from this string became your graal.
But I'm pretty sure that the following snippet answers to your real X problem:
你有一个XY问题。你真正的X问题是将任意数量的对象传递给一个函数。在定义了包含这些对象的标识符的字符串之后,从该字符串中提取回对象的Y解决方案成为了您的平等对象。但我很确定以下代码片段可以解答您的真实X问题:
if pts > 2:
blal = []
for i in [2,pts]:
px = Point(l[i].x, l[i].y).move(dx, dy).x
py = Point(l[i].x, l[i].y).move(dx, dy).y
blal.append(Point(px,py))
mv = LineString(pt1, pt2, *blal)
It's a facility offered by Python to pass arbitrary number of arguments to a function, not present in all programming languages. Would be a pity to complicate one's life , not using it.
它是Python提供的一种工具,可以将任意数量的参数传递给函数,而不是所有编程语言都存在。将一个人的生活复杂化而不是使用它会是一种遗憾。
I think that new members should be informed, or even prevented, not to upvote and accept answers too rapidly.
我认为新成员应该被告知,甚至被阻止,不要过快地投票和接受答案。
EDIT
I think that you can replace the code block in your question with this one:
我认为你可以用这个替换你问题中的代码块:
from itertools import chain
class Line(object):
def __init__(self, pt1, pt2, *pt):
self.vertices = map(lambda x: Point(*x),
chain((pt1,pt2), pt))
def __getitem__(self, key):
return Point(*self.vertices[key])
def move(self, dx, dy):
return LineString(*[ Point(Point(v.x, v.y).move(dx, dy).x,
Point(v.x, v.y).move(dx, dy).y)
for v in self.vertices])
You could even define Point()
in such a way that it would accept a couple (tuple, list... , I dont't know what your pt
s are) instead of elements of pt
So, you could write Point(x)
instead of Point(*x)
and
你甚至可以用这样的方式定义Point(),它会接受一对(元组,列表......,我不知道你的pts是什么)而不是pt的元素所以你可以写Point(x)代替Point(* x)和
self.vertices = map(Point, chain((pt1,pt2), pt))
instead of
代替
self.vertices = map(lambda x: Point(*x),
chain((pt1,pt2), pt))
but would need to write Point((v.x,v.y))
instead of Point(v.x,v.y)
但需要写Point((v.x,v.y))而不是Point(v.x,v.y)
#3
2
Python methods take arbitrary argument lists. What this means is that your function can take any number of arguments.
Python方法采用任意参数列表。这意味着你的函数可以使用任意数量的参数。
Here is an example:
这是一个例子:
def foo(*args, **kwargs):
print args
foo('a','b','c','d')
Now, suppose you wanted to pass a list with values in it as arguments:
现在,假设您想要将包含值的列表作为参数传递:
mylist = ['a','b','c','d']
foo(mylist)
Now this will result in:
现在这将导致:
(['a', 'b', 'c', 'd'],)
A tuple with your list as the first argument. What we want is the same affect as foo('a','b','c','d')
. To get that, we need to expand the list, like this:
以列表作为第一个参数的元组。我们想要的是与foo相同的影响('a','b','c','d')。为此,我们需要扩展列表,如下所示:
foo(*mylist)
Now you'll get the same result:
现在你会得到相同的结果:
('a', 'b', 'c', 'd')
Taking this and applying it to your problem:
考虑到这一点并将其应用于您的问题:
def foo(*args, **kwargs):
print "Total arguments: {}".format(len(args))
v = "a, b, c"
>>> foo(v)
Total arguments: 1
>>> foo(*v.split(','))
Total arguments: 3