2017-11-27 9 views
-1

이 Java 코드를 Python에 다시 쓰려고합니다. 이것은 (완벽하게 작동) 자바 코드 :Python에서 클래스를 초기화하지 않고 클래스 메서드 호출

public class Main { 
    private static Pager demandPager; 
    private static ArrayList<Process> runningProcesses = new ArrayList<Process>(); 
    private static ArrayList<Process> finishedProcesses = new ArrayList<Process>(); 
    private static int numProcesses; 
    private static int numRefPerProcess; 

    private static int clock; 
    private final static int QUANTUM = 3; 

    private static File randNum; 
    private static Scanner randReader; 

    public static void main(String[] args) { 
     readInput(args); 
     initializeRandNums(); 

     int prIdx = 0; 
     while(runningProcesses.size() > 0) { 
      Process p = runningProcesses.get(prIdx); 
      for (int ref = 0; ref < QUANTUM; ref++) { 
       demandPager.processRef(p, clock, randReader); 
       p.setCurrentReference(p.c 

alcNextReference(randReader)); 
       p.incrRefsMade(); 

      clock++; 

      if (p.getRefsMade() == numRefPerProcess) { 
       finishedProcesses.add(p); 
       runningProcesses.remove(p); 
       prIdx--; 
       break; 
      } 
     } 

     if (prIdx == numProcesses-1) { 
      prIdx = 0; 
     } 
     else { 
      prIdx++; 
     } 

    } 
    printOutput(args); 
} 

public static void readInput(String[] args) { 
    if (args.length != 6) { 
     System.out.println("Please input the machine size, page size, process size, job mix, number of references per process, and the replacement algorithm."); 
     System.exit(0); 
    } 

    demandPager = new Pager(Integer.parseInt(args[0]), Integer.parseInt(args[1])); 
    Page.setSize(Integer.parseInt(args[1])); 
    Process.setSize(Integer.parseInt(args[2])); 
    initializeProcesses(args[3]); 
    numRefPerProcess = Integer.parseInt(args[4]); 
    demandPager.setReplacementAlgo(args[5]); 
} 

This is the Page Class

import java.util.ArrayList; 

public class Page { 
    private static int size; 
    private int timeEvicted; 
    private int timeLoaded; 
    private int timeLastUsed; 

    private ArrayList<Integer> referencedWords; 



private int frameId; 
    private int pageId; 
    private Process ownerProcess; 
    private boolean ifLoaded; 

    public Page(int frame) { 
     frameId = frame; 
     pageId = -1; 
     timeEvicted = 0; 
    timeLoaded = 0; 
    ifLoaded = false; 
    ownerProcess = null; 
    referencedWords = new ArrayList<Integer>(); 
} 

public void initalize(Process owner, int pgId, int refdWord, boolean ifLoad) { 
    ownerProcess = owner; 
    pageId = pgId; 
    addRefdWord(refdWord); 
    ifLoaded = ifLoad; 
} 

public static void setSize(int s) { 
    size = s; 
} 

public void setPageId(int p) { 
    pageId = p; 
} 

파이썬으로 변환에서 내 시도는 다음과 같다 :

from Process import Process 
from Page import Page as Page 
from Pager import Pager 
from FrameTable import FrameTable 
import sys 
#store random numbers in a list 
r = open('random.txt') 
l = [] 
for c in r: 
    l.append(int(c)) 
runningProcesses = [] 
finishedProcesses = [] 
def main(): 
    #read input 
    machineSize = int(sys.argv[1]) 
    pageSize = int(sys.argv[2]) 
    processSize = int(sys.argv[3]) 
    jobMix = int(sys.argv[4]) 
    numOfRefPerProcess = int(sys.argv[5]) 
    replacementAlgo = (sys.argv[6]) 
    demandPager = Pager(machineSize, pageSize) 
    Page.setSize(pageSize) 
    Process.setSize(processSize) 
    setProc(jobMix) 
    demandPager.setAlg(replacementAlgo) 

    index = 0 
    while(runningProcesses.size() > 0): 
     p = runningProcesses.get(index) 
     for i in range(3): 
      demandPager.processRef(p, clock, randReader) 
      p.setCurrentReference(p.calcNextReference(randReader)) 
      p.incrRefsMade() 

      clock+=1 

      if (p.getRefsMade() == numRefPerProcess): 
       finishedProcesses.add(p) 
       runningProcesses.remove(p) 
       index-=1 
       break 
     if (index == numProcesses-1): 
      index = 0 
     else: 
      index+=1 
    print "print ng....." 
    printOutput(args) 

The Class Page:

class Page: 
    def __init__(self, frame): 
     self.frameId = frame 
     self.pageId = -1 
     self.timeEvicted = 0 
     self.timeLoaded = 0 
     self.ifLoaded = False 
     self.ownerProcess = 0 
     self.referencedWords = [] 
     self.size = 0 

    def initalize(owner, pgId, refdWord, ifLoad): 
     self.ownerProcess = owner 
     self.pageId = pgId 
     addRefdWord(refdWord) 
     self.ifLoaded = ifLoad 

    @classmethod 
    def setSize(cls, s): 
     size = s 

    def setPageId(self,p): 
     self.pageId = p 

내 문제입니다 이 코드를 실행할 때마다이 오류가 발생합니다. TypeError : 바인딩되지 않은 메서드 setSize()는 첫 번째 인수로 Process 인스턴스와 함께 호출해야합니다 (대신 int 인스턴스가 사용됨)

왜 그런지는 잘 모르겠습니다. 이것은 파이썬에서 합법적이지 않습니까? 아니면 뭔가 빠져 있습니까?

+0

정확한 오류, 추적 및 모든 것을 게시하십시오. – chepner

+0

오류에 대해서는 확실치 않지만, 파이썬의'setSize' 메쏘드는 상관 없습니다. 아마도'cls.size = s'를 원할 것입니다. –

+1

잠깐, 파이썬 2를 들으셨습니까? 그렇다면'classmethod'를 사용하려면'object'를 명시 적으로 상속 받아야합니다. 그렇지 않으면 구식 클래스이므로 데코레이터가 올바르게 작동하지 않습니다. –

답변

1

Python은 Java의 정적 변수와 정확히 동일하지 않습니다. 그러나 클래스 본문 내에 있지만 멤버 함수 외부에 선언 된 클래스 변수는 있습니다. 이 변수는 "."앞에있는 클래스 이름을 사용하여 액세스합니다. 인스턴스 대신 원하는 것은 다음과 같습니다.

class Page: 
    size = 0 # Moved out of __init__ 
    def __init__(self, frame): 
     self.frameId = frame 
     self.pageId = -1 
     self.timeEvicted = 0 
     self.timeLoaded = 0 
     self.ifLoaded = False 
     self.ownerProcess = 0 
     self.referencedWords = [] 

    def initalize(owner, pgId, refdWord, ifLoad): 
     self.ownerProcess = owner 
     self.pageId = pgId 
     addRefdWord(refdWord) 
     self.ifLoaded = ifLoad 

    @staticmethod # Changed from classmethod 
    def setSize(s): 
     Page.size = s # Syntax changed 

    def setPageId(self,p): 
     self.pageId = p 

파이썬에서는 setter 기능을 제공하는 데 반드시 좋은 스타일로 간주되지 않습니다. setSize 함수를 완전히 제거한 경우 클라이언트 코드는 함수 호출이 아닌 Page.size = s을 사용하여 간단히 크기를 설정할 수 있습니다. setter 함수를 많이 작성하여 얻는 것은 거의 없습니다.

+0

감사합니다! getter 함수를 변경할 수있는 비슷한 방법이 있습니까? – MarkJ

+0

새로운 스타일의 클래스 인 cls.size = s 만 있으면 클래스 메소드를 변경할 필요가 없습니다. – jonrsharpe

+0

@jonrsharpe이 경우에는 true이지만 클래스가'Page'에서 파생되면 차이가 있습니다. –