개체 목록에 대해 동일한 메서드를 호출하는 방법은 무엇입니까?
다음과 같은 코드를 가정하십시오.
class Base:
def start(self):
pass
def stop(self)
pass
class A(Base):
def start(self):
... do something for A
def stop(self)
.... do something for A
class B(Base):
def start(self):
def stop(self):
a1 = A(); a2 = A()
b1 = B(); b2 = B()
all = [a1, b1, b2, a2,.....]
이제 모든 목록의 각 개체에 대해 start 및 stop 메서드를 호출하고 싶습니다. 다음과 같은 함수를 작성하는 것 외에는 우아한 방법이 있습니까?
def start_all(all):
for item in all:
item.start()
def stop_all(all):
* _all () 함수는 매우 간단하여 몇 가지 메서드의 경우 함수를 작성하기 만하면됩니다. 동일한 함수가 많으면 일반 함수를 작성할 수 있습니다.
def apply_on_all(seq, method, *args, **kwargs):
for obj in seq:
getattr(obj, method)(*args, **kwargs)
또는 함수 팩토리를 만듭니다.
def create_all_applier(method, doc=None):
def on_all(seq, *args, **kwargs):
for obj in seq:
getattr(obj, method)(*args, **kwargs)
on_all.__doc__ = doc
return on_all
start_all = create_all_applier('start', "Start all instances")
stop_all = create_all_applier('stop', "Stop all instances")
...
이것은 작동합니다
all = [a1, b1, b2, a2,.....]
map(lambda x: x.start(),all)
간단한 예
all = ["MILK","BREAD","EGGS"]
map(lambda x:x.lower(),all)
>>>['milk','bread','eggs']
그리고 python3에서
all = ["MILK","BREAD","EGGS"]
list(map(lambda x:x.lower(),all))
>>>['milk','bread','eggs']
좀 더 파이썬적인 방법이있을 것 같지만 아직 찾지 못했습니다.
여러 객체에 대해 동일한 함수 (메서드가 아님)를 호출하는 경우 가끔 "맵"을 사용합니다.
map(do_something, a_list_of_objects)
이것은 다음과 같은 코드를 대체합니다.
do_something(a)
do_something(b)
do_something(c)
...
그러나 보행자 "for"루프로도 달성 할 수 있습니다.
for obj in a_list_of_objects:
do_something(obj)
The downside is that a) you're creating a list as a return value from "map" that's just being throw out and b) it might be more confusing that just the simple loop variant.
You could also use a list comprehension, but that's a bit abusive as well (once again, creating a throw-away list):
[ do_something(x) for x in a_list_of_objects ]
For methods, I suppose either of these would work (with the same reservations):
map(lambda x: x.method_call(), a_list_of_objects)
or
[ x.method_call() for x in a_list_of_objects ]
So, in reality, I think the pedestrian (yet effective) "for" loop is probably your best bet.
The approach
for item in all:
item.start()
is simple, easy, readable, and concise. This is the main approach Python provides for this operation. You can certainly encapsulate it in a function if that helps something. Defining a special function for this for general use is likely to be less clear than just writing out the for loop.
maybe map
, but since you don't want to make a list, you can write your own...
def call_for_all(f, seq):
for i in seq:
f(i)
then you can do:
call_for_all(lamda x: x.start(), all)
call_for_all(lamda x: x.stop(), all)
by the way, all is a built in function, don't overwrite it ;-)
Taking @Ants Aasmas answer one step further, you can create a wrapper that takes any method call and forwards it to all elements of a given list:
class AllOf:
def __init__(self, elements):
self.elements = elements
def __getattr__(self, attr):
def on_all(*args, **kwargs):
for obj in self.elements:
getattr(obj, attr)(*args, **kwargs)
return on_all
That class can then be used like this:
class Foo:
def __init__(self, val="quux!"):
self.val = val
def foo(self):
print "foo: " + self.val
a = [ Foo("foo"), Foo("bar"), Foo()]
AllOf(a).foo()
Which produces the following output:
foo: foo foo: bar foo: quux!
With some work and ingenuity it could probably be enhanced to handle attributes as well (returning a list of attribute values).
Starting in Python 2.6 there is a operator.methodcaller function.
So you can get something more elegant (and fast):
from operator import methodcaller
map(methodcaller('method_name'), list_of_objects)
참고URL : https://stackoverflow.com/questions/2682012/how-to-call-same-method-for-a-list-of-objects
'Program Tip' 카테고리의 다른 글
자바 스크립트 사용을 위해 C #의 이스케이프 따옴표 (0) | 2020.12.02 |
---|---|
Python에서 문자열 찾기의 예 (0) | 2020.12.02 |
ZooKeeper가 실행 중인지 또는 명령 프롬프트에서 실행 중인지 확인하는 방법은 무엇입니까? (0) | 2020.12.02 |
jQuery : 선택한 라디오 버튼에 대한 부모 tr 가져 오기 (0) | 2020.12.02 |
소프트웨어 버전과 같이 점으로 구분 된 숫자 목록 정렬 (0) | 2020.12.02 |