c******n 发帖数: 4965 | 1 I have the following code, which includes a closure:
class MyClass:
outer_var = 1
def run():
class Inner():
def run_inner():
print self.outer_var
at the last line, I want to refer to the member of the outer class,
but now the "self" actually refers to Inner class.
this is because python does not have a proper scope. so apart from
assigning outer_var to a tmp var, is there any way to refer to
outer_var?
thanks | S*A 发帖数: 7142 | 2 看了这么多无聊问题,这个问题我喜欢。
首先,你的 run() 应该有参数 self.
你可以把这个 outter self 当参数传进去。
Python 就是两个 scope, local vs global. 剩下的都是用参数传的。
def run_inner(self, outter_self = self):
...
应该就可以了,这个 code 我完全没有试过,错了不保。
【在 c******n 的大作中提到】 : I have the following code, which includes a closure: : class MyClass: : outer_var = 1 : def run(): : class Inner(): : def run_inner(): : print self.outer_var : at the last line, I want to refer to the member of the outer class, : but now the "self" actually refers to Inner class. : this is because python does not have a proper scope. so apart from
| c******n 发帖数: 4965 | 3 thanks,
but there is still a limitation: python does not have anonymous class,
so I wanted to print
"In BBB1"
"In BBB2" by the following code
import threading
class VV:
x="1"
def __init__(self, x ):
self.x = x
def blah(self,xx):
l = []
for a in [ 1 , 2 ]:
class BB:
def run(self):
print "IN BBB%d" % a
l.append(BB())
l[0].run();
l[1].run();
v = VV("2")
v.blah("A")
but in practice, it gives out 2 lines of "In BBB2", because class BB
def is modified.
is there a way to do this in python?
【在 S*A 的大作中提到】 : 看了这么多无聊问题,这个问题我喜欢。 : 首先,你的 run() 应该有参数 self. : 你可以把这个 outter self 当参数传进去。 : Python 就是两个 scope, local vs global. 剩下的都是用参数传的。 : def run_inner(self, outter_self = self): : ... : 应该就可以了,这个 code 我完全没有试过,错了不保。
| S*A 发帖数: 7142 | 4 你还没有搞明白 a 在这里是个 global symbol.
如果你在另外一个函数里面跑 l[0].run() 然后这个 a 应该就找不到了。
而且这个不是好的 python 的用法,因为 a 的 scope 特别隐晦。
你可以创建不同的 class. __class__.a 设定到不同的值。
还有更加难懂的 meta class. 但是 meta class 是不能通过
class statement 来定义的。
【在 c******n 的大作中提到】 : thanks, : but there is still a limitation: python does not have anonymous class, : so I wanted to print : "In BBB1" : "In BBB2" by the following code : import threading : class VV: : x="1" : def __init__(self, x ): : self.x = x
| b********e 发帖数: 58 | 5 Regarding to your example "IN BBB%d", it does feel like a man-made problem/
argument. It can easily be fixed by passing variable a in the __init__
method of class BBB. Or do I miss anything here? | c******n 发帖数: 4965 | 6 it is possible to do it that way, but it's cumbersome
consider that you have 10 vars to be accessed through closure,
you would have to create 10 useless member vars, and have to access
them through self., adding much more typing.
scripting like python and perl, a very important thing is "idiom",
stuff like this has been done before, and people have found the best
way to do it, it's best to follow.
I have found from stackOverflow that the best way here is to wrap the
closure content like the following, for my last example:
def produce_BB(a=a):
return BB()
## the rest is the same
class BB:
def run(self):
print "IN BBB%d" % a
# but in main code, change direct constructor call of BB()
# to the wrapper
#l.append(BB())
l.append(produce_BB())
this way, the only thing u add is the 3 lines of wrapper, and indent
the class BB block. it's very localized. the nice thing is that you
don't even have to change the var name of "a", and introduce something
like "inner_a"
problem/
__init__
【在 b********e 的大作中提到】 : Regarding to your example "IN BBB%d", it does feel like a man-made problem/ : argument. It can easily be fixed by passing variable a in the __init__ : method of class BBB. Or do I miss anything here?
| b********e 发帖数: 58 | 7 Cool. I learned something here. Thanx. | S*A 发帖数: 7142 | 8 Clever, it can work that way. But I still don't like it.
Why? Because it is very cryptic. It is very hard to spot
the "a" is referencing the the argument in scopes that is
two levels above.
Typing self is not the reason to avoid it. In this case,
using "self.a" is better and clear than "a", because it
clearly said "a" is from some other scope.
There are constructive ways to create your class BB.
e.g. Mix class BB with a base class which provide self.a etc.
【在 c******n 的大作中提到】 : it is possible to do it that way, but it's cumbersome : consider that you have 10 vars to be accessed through closure, : you would have to create 10 useless member vars, and have to access : them through self., adding much more typing. : scripting like python and perl, a very important thing is "idiom", : stuff like this has been done before, and people have found the best : way to do it, it's best to follow. : I have found from stackOverflow that the best way here is to wrap the : closure content like the following, for my last example: : def produce_BB(a=a):
| c******n 发帖数: 4965 | 9 我比较喜欢这样搞,
因为你可以把前面的wrapper 3 line 单独放到一块儿,
然后写足够的comment, 这样读code 的人可以很快意识到
produce_BB() => new BB()
or your can even name it newBB(), as is often done in java, that way
people can realize what it means, without trying to figure out how it works.
but of course for people familiar with the idiom, they can know immediately.
it's not that complicated, when people see
anonymous class and closure in java, they still take a little while to
get used to it, but quickly it feels very natural to use it that way.
【在 S*A 的大作中提到】 : Clever, it can work that way. But I still don't like it. : Why? Because it is very cryptic. It is very hard to spot : the "a" is referencing the the argument in scopes that is : two levels above. : Typing self is not the reason to avoid it. In this case, : using "self.a" is better and clear than "a", because it : clearly said "a" is from some other scope. : There are constructive ways to create your class BB. : e.g. Mix class BB with a base class which provide self.a etc.
| M*P 发帖数: 6456 | 10 不错,第一次了解closure的概念。不过倒是用过。隐约觉得会有问题,就不常用了。
works.
immediately.
【在 c******n 的大作中提到】 : 我比较喜欢这样搞, : 因为你可以把前面的wrapper 3 line 单独放到一块儿, : 然后写足够的comment, 这样读code 的人可以很快意识到 : produce_BB() => new BB() : or your can even name it newBB(), as is often done in java, that way : people can realize what it means, without trying to figure out how it works. : but of course for people familiar with the idiom, they can know immediately. : it's not that complicated, when people see : anonymous class and closure in java, they still take a little while to : get used to it, but quickly it feels very natural to use it that way.
| r****t 发帖数: 10904 | 11 your produceBB calls should be passed "a" rather than having a referenced
from within. This is typical factory pattern, nothing specific to python.
【在 c******n 的大作中提到】 : it is possible to do it that way, but it's cumbersome : consider that you have 10 vars to be accessed through closure, : you would have to create 10 useless member vars, and have to access : them through self., adding much more typing. : scripting like python and perl, a very important thing is "idiom", : stuff like this has been done before, and people have found the best : way to do it, it's best to follow. : I have found from stackOverflow that the best way here is to wrap the : closure content like the following, for my last example: : def produce_BB(a=a):
| S*A 发帖数: 7142 | 12 Agree, that is the same reason I argue that style works, but
not very pythonish. Look at the stander python library, there
are tons of python code does complicate stuff. I haven't see
an usage like that so far. It is against python's simple and
obvious guideline.
【在 r****t 的大作中提到】 : your produceBB calls should be passed "a" rather than having a referenced : from within. This is typical factory pattern, nothing specific to python.
|
|