2014-11-22 2 views
0

클래스 메서드를 목록에 저장하고 루프를 통해 실행해야합니다. 데코레이터를 정의하고 클래스 메소드를 목록에 추가하는 데 사용합니다. 클래스는 별도의 모듈에 정의되어 있으며 목록에서 main I 루프를 통해 해당 목록에 저장된 클래스 메서드를 호출합니다.목록 개체에 저장된 데코 레이팅 된 클래스 메서드를 실행하는 방법은 무엇입니까?

형식 오류 : example_01 (1 개) 필요한 위치 인수 누락 : 나는 좀 내가 실행하는 클래스 바의 인스턴스를 생성해야합니다 것을 알고있어 '자기'

내가 메인 실행하면, 나는 오류가 발생했습니다 그 방법을 사용하면 목록을 사용할 수 없게됩니다. 그런 구조를 사용하는 올바른 방법은 무엇입니까? 도와주세요 ...

나는 파이썬 3.4

감사

mybar.py 
======== 

examples = list() 

def example(fn): 
    try: name = 'Example %d' % int(fn.__name__[7:]) 
    except: name = fn.__name__ 

    def wrapped(): 
     print('Running: %s\n' % name) 
     fn() 
     print('\n') 
    examples.append(wrapped) 
    return wrapped 


class Bar: 
    def __init__(self): 
     self.message = "I'm %s" % (__name__) 

    @example 
    def example_01(self): 
     print(self.message) 
     print("Executing example_01") 

    @example 
    def example_02(selfs): 
     print(self.message) 
     print("Executing example_02") 

main.py 
======= 
from bar import mybar 


def main(): 
    for example in mybar.examples: 
     example() 


if __name__ == "__main__": 
    main() 

내가 각 클래스 메소드를 위해 장식을 @classmethod 사용하려면 코드를 수정하고 작동

을 사용하고 있습니다,하지만 난하지 않습니다 이유를 이해하십시오. 나는 Bar를 사용하여 example()을 명시 적으로 호출 할 필요가 없다. python doc에 문서화 된 def example_01 (cls)와 같은 클래스 함수의 인수에 클래스 객체를 제공하지 마십시오. 누군가가 설명해 주시겠습니까

mybar.py 
======= 
class Bar: 
data = 25 
def __init__(self): 
    self.message = "I'm %s" % (__name__) 
    Bar.data = 30 

@classmethod 
@example 
def example_01(): 
    print("Executing example_01") 
    print("Data: ", Bar.data) 

@classmethod 
@example 
def example_02(): 
    print("Executing example_02") 
    print("Data: ", Bar.data) 

출력 :

파이썬에서
Running: example_01 
Executing example_01 
Data: 25 
Running: example_02 
Executing example_02 
Data: 25 

답변

1

(인수 일반 목록 소요) 함수를 구별하고 인수를 취하는 방법 (플러스 특별 self가 또는 cls 인수). 함수가 클래스 네임 스페이스 내부의 변수에 할당되면 함수가 메서드가됩니다.

example_01example_02 기능을 꾸미고있는 시점에 실제로는 기능이 아니라 일반 기능입니다. examples에 추가하는 함수이므로 결과 클래스 메서드는 호출되지 않습니다.

쉽게 해결할 수 없습니다. 먼저 @example으로 꾸미거나 (아직 클래스 메서드가 없습니다), 또는 @classmethod으로 꾸미십시오. (클래스 메서드가 아닌 중간 개체 만 있으면됩니다.) 최종 클래스 메서드를 얻는 유일한 방법은 이 할당 된 후에 메서드를 검색하는 것입니다. 이는 분명히 데코레이터에서 수행 할 수 없습니다.

가장 쉬운 것은 간단한 방법으로 examples에 클래스 메소드를 전부 장식을 삭제하고 지정하는 것입니다 : 당신이 정말 장식을 사용하려는 경우, 당신은 examples에 래퍼를 넣을 수

examples = [Bar.example_01, Bar.example_02] 

하는 클래스 이름에서 getattr을 사용하여 클래스 메서드를 검색하고 을 수정하지 않고 함수 fn을 반환합니다.

message 변수가 Bar 클래스의 생성자에 설정되었으므로 액세스하려면 Bar 인스턴스가 필요합니다. 더미 인스턴스를 만들지 않고 클래스 메소드에서 변수에 액세스하려면 클래스 네임 스페이스에 변수를 설정해야합니다.그러나 __name__ 변수가 설정되어 있지 않으므로 기본적으로 message 변수를 사용할 수 없습니다. 또한 클래스 메서드에서 첫 번째 인수는 이 아닌 클래스 자체이며 self (인스턴스)이 아니며 \n으로 끝나는 print 문은 이중 줄 바꿈을 발생시킵니다.

같이 최종 코드를 볼 수있는 것입니다 : __ 당신이 장식을 사용하지 않으려면

examples = list() 

def example(fn): 
    def wrapped(): 
     print("Running: %s" % fn.__name__) 
     getattr(Bar, fn.__name__)() 
     print() 
    examples.append(wrapped) 
    return fn 

class Bar: 
    @classmethod 
    @example 
    def example_01(cls): 
     print("I'm %s" % cls.__name__) 
     print("Executing example_01") 

    @classmethod 
    @example 
    def example_02(cls): 
     print("I'm %s" % cls.__name__) 
     print("Executing example_02") 
0

, 당신은 클래스의 방법의 목록을 검색하고 방법 __getattribute을 사용할 수 있습니다()를 호출합니다 클래스의 인스턴스로부터의 각 메소드. 다음은 코드입니다.

import types 

class Bar(object): 

    def __init__(self): 
     self.message = "I'm %s" % (self.__class__.__name__) 

    def example_01(self): 
     print(self.message) 
     print("Executing example_01") 

    def example_02(self): 
     print(self.message) 
     print("Executing example_02") 

examples = list() 
testBar = Bar() 
methods = Bar.__dict__ 
for k, v in methods.items(): 
    if isinstance(v, types.FunctionType): 
     if k != '__init__': 
      examples.append(testBar.__getattribute__(k)) 

def main(): 
    for method in examples: 
     method() 

if __name__ == '__main__': 
    main() 
관련 문제