programing

수업 방법의 목적은 무엇입니까?

goodcopy 2022. 12. 26. 21:40
반응형

수업 방법의 목적은 무엇입니까?

저는 Python을 독학하고 있는데, 가장 최근에 배운 교훈은 Python은 Java가 아니라는 것입니다. 그래서 저는 Class 메서드를 모두 함수로 바꾸는데 오랜 시간을 보냈습니다.

이제 클래스 메서드를 사용할 필요가 없다는 것을 알게 되었습니다.static자바어로 된 메서드인데 언제 사용할지 모르겠어요.Python Class 메서드에 대해 제가 찾을 수 있는 모든 조언은 나와 같은 신입사원들과 비슷합니다. 그리고 표준 문서는 그것들을 논할 때 가장 불투명합니다.

Python에서 Class 메서드를 사용하는 좋은 예가 있거나 Class 메서드를 언제 현명하게 사용할 수 있는지 알려주실 수 있나요?

클래스 메서드는 특정 인스턴스에 고유하지 않지만 클래스와 관련된 메서드가 필요할 때 사용합니다.가장 흥미로운 점은 Java의 정적 메서드나 Python의 모듈 수준 함수에서는 불가능한 서브클래스에 의해 덮어쓸 수 있다는 것입니다.

MyClass MyClass 출하시,스터브 에서는, 「MyClass」( 「」, 「Dependency Injection Stub」)가 됩니다classmethod그러면 하위 클래스에서 사용할 수 있습니다.

공장 메서드(대체 컨스트럭터)는 클래스 메서드의 전형적인 예입니다.

기본적으로 클래스 메서드는 클래스의 네임스페이스에 자연스럽게 들어가지만 클래스의 특정 인스턴스와 연관되지 않는 메서드를 원하는 경우 언제든지 적합합니다.

를 들어 우수한 유니패스모듈에서는 다음과 같습니다.

현재 디렉토리

  • Path.cwd()
    • 디렉토리를 「 」 「 」 「 」 「 」★★★★★★★★★★★★★★★★★,Path("/tmp/my_temp_dir")이치노
  • .chdir()
    • 자신을 현재의 디렉토리로 합니다.

전체에 있기 에, 「 」는 「 」입니다.cwd메서드 「」, 「」의 cwd로 하다」Path method는 instance method여야 합니다.

...로... ★★★★★★★★★★★…Path.cwd()는 실제로 됩니다.Path예를 들어 공장에서의 방법이라고 생각할 수 있을 것 같습니다만...

해 주세요은 디스패치의 데 이 됩니다.「 「 」를 할 수 .일반적인 방법은 디스패치의 상세 내용을 숨기는데 도움이 됩니다.입력할 수 있습니다.myobj.foo()정정의 에 대해 foo() 방법은 로 구현됩니다.myobj오브젝트의 클래스 또는 상위 클래스 중 하나.이와 오브젝트를 할 수 .MyClass.foo() foo()하고 있습니다.MyClass전용 버전이 필요하거나 부모 클래스가 콜을 처리하도록 하고 있는지 여부입니다.

클래스 메서드는 실제 인스턴스 작성 에 셋업 또는 계산을 수행할 때 필수적입니다.인스턴스가 존재할 때까지는 해당 인스턴스를 메서드콜의 디스패치포인트로 사용할 수 없습니다.SQL Chemy 소스 코드에서 좋은 예를 볼 수 있습니다.dbapi(): class 메음음 음음음 음음음 class class class class class:: : class: 。

https://github.com/zzzeek/sqlalchemy/blob/ab6946769742602e40fb9ed9dde5f642885d1906/lib/sqlalchemy/dialects/mssql/pymssql.py#L47

「 」는, 「 」를 .dbapi()method는 데이터베이스 백엔드가 온디멘드로 필요한 벤더 고유의 데이터베이스 라이브러리를 Import하기 위해 사용하는 클래스 메서드입니다.이것은 특정 데이터베이스 접속 인스턴스가 작성되기 전에 실행해야 하기 때문입니다.단, 다른 지원 메서드를 호출할 수 있도록 하기 위해 단순한 함수 또는 정적 함수일 수는 없습니다.마찬가지로 부모 클래스보다 하위 클래스에 구체적으로 작성해야 할 수 있습니다.또한 함수 또는 정적 클래스에 디스패치하면 "잊어버리고" 초기화 중인 클래스에 대한 지식이 손실됩니다.

최근에는 프로그래밍 방식으로 설정할 수 있는 로깅레벨에 따라 다양한 양의 출력을 출력할 수 있는 매우 가벼운 로깅클래스를 원했습니다.그러나 디버깅 메시지, 오류 또는 경고를 출력할 때마다 클래스를 인스턴스화하고 싶지 않았습니다.또한 이 로깅 기능의 기능을 캡슐화하여 글로벌 선언 없이 재사용할 수 있도록 하고 싶었습니다.

클래스 변수를 했습니다.@classmethod코레데

간단한 Logging 클래스로 다음 작업을 수행할 수 있습니다.

Logger._level = Logger.DEBUG

그리고 내 코드에서 디버깅 정보를 많이 내뱉으려면 코드화만 하면 된다.

Logger.debug( "this is some annoying message I only want to see while debugging" )

에러가 발생할 수 있습니다.

Logger.error( "Wow, something really awful happened." )

「실가동」환경에서는, 다음과 같이 지정할 수 있습니다.

Logger._level = Logger.ERROR

이제 오류 메시지만 출력됩니다.디버깅 메시지는 인쇄되지 않습니다.

제 수업은 다음과 같습니다.

class Logger :
    ''' Handles logging of debugging and error messages. '''

    DEBUG = 5
    INFO  = 4
    WARN  = 3
    ERROR = 2
    FATAL = 1
    _level = DEBUG

    def __init__( self ) :
        Logger._level = Logger.DEBUG

    @classmethod
    def isLevel( cls, level ) :
        return cls._level >= level

    @classmethod
    def debug( cls, message ) :
        if cls.isLevel( Logger.DEBUG ) :
            print "DEBUG:  " + message

    @classmethod
    def info( cls, message ) :
        if cls.isLevel( Logger.INFO ) :
            print "INFO :  " + message

    @classmethod
    def warn( cls, message ) :
        if cls.isLevel( Logger.WARN ) :
            print "WARN :  " + message

    @classmethod
    def error( cls, message ) :
        if cls.isLevel( Logger.ERROR ) :
            print "ERROR:  " + message

    @classmethod
    def fatal( cls, message ) :
        if cls.isLevel( Logger.FATAL ) :
            print "FATAL:  " + message

그리고 그것을 테스트하는 몇 가지 코드는 다음과 같습니다.

def logAll() :
    Logger.debug( "This is a Debug message." )
    Logger.info ( "This is a Info  message." )
    Logger.warn ( "This is a Warn  message." )
    Logger.error( "This is a Error message." )
    Logger.fatal( "This is a Fatal message." )

if __name__ == '__main__' :

    print "Should see all DEBUG and higher"
    Logger._level = Logger.DEBUG
    logAll()

    print "Should see all ERROR and higher"
    Logger._level = Logger.ERROR
    logAll()

대체 컨스트럭터가 대표적인 예입니다.

사용자가 웹 사이트에 로그인하면 사용자 이름과 비밀번호에서 User() 개체가 인스턴스화됩니다.

로그인하기 위해 사용자가 없는 사용자 객체가 필요한 경우(예를 들어 admin 사용자가 다른 사용자 계정을 삭제하려고 할 수 있으므로 해당 사용자를 인스턴스화하고 삭제 메서드를 호출해야 합니다.

사용자 개체를 잡기 위한 클래스 메서드가 있습니다.

class User():
    #lots of code
    #...
    # more code

    @classmethod
    def get_by_username(cls, username):
        return cls.query(cls.username == username).get()

    @classmethod
    def get_by_auth_id(cls, auth_id):
        return cls.query(cls.auth_id == auth_id).get()

가장 확실한 답은 AmanKow의 대답이라고 생각합니다.요컨대 코드를 어떻게 정리할 것인가 하는 것입니다.모든 것을 모듈의 네임스페이스에 랩된 모듈레벨 함수로 쓸 수 있습니다.

module.py (file 1)
---------
def f1() : pass
def f2() : pass
def f3() : pass


usage.py (file 2)
--------
from module import *
f1()
f2()
f3()
def f4():pass 
def f5():pass

usage1.py (file 3)
-------------------
from usage import f4,f5
f4()
f5()

위의 절차 코드는 잘 정리되어 있지 않습니다.단 3개의 모듈만 지나면 혼란스러워집니다.각각의 방법은 무엇입니까?함수에 대해 긴 설명명을 사용할 수 있지만(자바 등), 코드는 매우 빠르게 관리할 수 없습니다.

오브젝트 지향적인 방법은 코드를 관리 가능한 블록으로 분할하는 것입니다.클래스 & 오브젝트 및 함수는 오브젝트 인스턴스 또는 클래스와 관련지을 수 있습니다.

클래스 함수를 사용하면 모듈 수준 함수와 비교하여 코드 내에서 다른 수준의 분할을 얻을 수 있습니다.따라서 클래스 내에서 관련 함수를 그룹화하여 해당 클래스에 할당한 태스크에 보다 고유하게 만들 수 있습니다.예를 들어 파일 유틸리티 클래스를 만들 수 있습니다.

class FileUtil ():
  def copy(source,dest):pass
  def move(source,dest):pass
  def copyDir(source,dest):pass
  def moveDir(source,dest):pass

//usage
FileUtil.copy("1.txt","2.txt")
FileUtil.moveDir("dir1","dir2")

이 방법은 보다 유연하고 유지보수가 용이하며, 기능을 함께 그룹화하여 각 기능이 수행하는 작업을 보다 명확하게 합니다.또한 이름 경합을 방지할 수 있습니다.예를 들어 함수 복사가 코드 내에서 사용하는 다른 Import된 모듈(네트워크 복사 등)에 존재할 수 있습니다.따라서 풀네임 FileUtil.copy()를 사용하면 문제를 제거하고 두 복사 기능을 동시에 사용할 수 있습니다.

호환되는 클래스에서 사용할 수 있는 일반 클래스 메서드를 작성할 수 있습니다.

예를 들어 다음과 같습니다.

@classmethod
def get_name(cls):
    print cls.name

class C:
    name = "tester"

C.get_name = get_name

#call it:
C.get_name()

★★★★★★★★★★★★★★★를 사용하지 않는 경우는@classmethod할 수 Classself의 인스턴스가 합니다.

def get_name(self):
    print self.name

class C:
    name = "tester"

C.get_name = get_name

#call it:
C().get_name() #<-note the its an instance of class C

솔직히?나는 정적 방법이나 클래스 방법의 용도를 찾은 적이 없다.글로벌 함수나 인스턴스 방식으로는 할 수 없는 작업은 아직 본 적이 없습니다.

Python이 Java처럼 개인 멤버와 보호된 멤버를 더 많이 사용한다면 달라질 것입니다.자바에서는 인스턴스의 프라이빗 멤버에 액세스하여 작업을 수행할 수 있는 정적 메서드가 필요합니다.Python에서는 거의 필요하지 않습니다.

일반적으로는 python의 모듈 레벨 네임스페이스만 더 잘 사용하면 static 메서드와 class 메서드를 사용할 수 있습니다.

예전에 PHP로 일했는데, 최근에는 '이 클래스 메서드는 어떻게 되어가고 있는가?'라고 자문하고 있었습니다.Python 매뉴얼은 매우 기술적이고 단어도 짧기 때문에 그 기능을 이해하는 데 도움이 되지 않습니다.구글 검색과 구글 검색에서 답을 찾았습니다. -> http://code.anjanesh.net/2007/12/python-classmethods.html.

클릭하기 귀찮으면.제 설명은 더 짧고 아래에 있습니다.:)

PHP에는 다음과 같은 정적 변수가 있습니다.


class A
{

    static protected $inner_var = null;

    static public function echoInnerVar()
    {
        echo self::$inner_var."\n";
    }

    static public function setInnerVar($v)
    {
        self::$inner_var = $v;
    }

}

class B extends A
{
}

A::setInnerVar(10);
B::setInnerVar(20);

A::echoInnerVar();
B::echoInnerVar();

출력은 두 경우 모두 20이 됩니다.

그러나 python에서는 @classmethod decorator를 추가할 수 있으므로 각각 출력 10과 20을 가질 수 있습니다.예:


class A(object):
    inner_var = 0

    @classmethod
    def setInnerVar(cls, value):
        cls.inner_var = value

    @classmethod
    def echoInnerVar(cls):
        print cls.inner_var


class B(A):
    pass


A.setInnerVar(10)
B.setInnerVar(20)

A.echoInnerVar()
B.echoInnerVar()

똑똑하지 않아?

수업 방법은 "의미적 설탕" 또는 "의미적 편의"를 제공합니다.

예: 개체를 나타내는 클래스 세트가 있습니다. 방법으로는 수업 방법을 하는 것이 것 .all() ★★★★★★★★★★★★★★★★★」find()User.all() ★★★★★★★★★★★★★★★★★」User.find(firstname='Guido')물론 모듈 수준의 기능을 사용하여 할 수 있습니다.

「훈련에 의한 프로그래머」가 아닌 경우는, 다음의 점에 도움이 됩니다.

인터넷 상이나 다른 곳에서는 기술적인 설명을 이해했다고 생각합니다만, 항상 「좋습니다만, 왜 필요합니까?」라고 하는 질문이 남았습니다.실용적인 사용 사례란 무엇입니까?"라고 묻자, 이제 삶은 다음과 같은 모든 것을 명확히 하는 좋은 예를 들어 다음과 같습니다.

멀티스레딩 모듈에 의해 인스턴스화된 클래스의 인스턴스 간에 공유되는 글로벌 공유 변수를 제어하기 위해 사용합니다.인간적인 언어로, 나는 딥 러닝을 위한 예를 병렬로 만드는 여러 에이전트를 실행하고 있다. (여러 플레이어가 동시에 ATARI 게임을 하고 각각의 게임 결과를 하나의 공통 저장소(SHARED VARILE)에 저장한다고 상상한다.)

다음 코드(메인/실행 코드)로 플레이어/에이전트를 인스턴스화합니다.

a3c_workers = [A3C_Worker(self.master_model, self.optimizer, i, self.env_name, self.model_dir) for i in range(multiprocessing.cpu_count())]
  • comp A3C_Worker의 프로세서코어 수만큼 플레이어를 만듭니다.에이전트 a3c_workers를 정의하는 클래스입니다.각 인스턴스는 그 클래스의 인스턴스 목록입니다(즉, 각 인스턴스는 해당 클래스의 인스턴스 목록입니다.

A3C_Worker 정의에서 모든 플레이어/에이전트에서 몇 개의 게임이 실행되었는지 알고 싶습니다. 따라서 모든 인스턴스에서 공유할 변수를 정의합니다.

class A3C_Worker(threading.Thread):
   global_shared_total_episodes_across_all_workers = 0

이제 근로자들은 게임을 마치면 게임이 끝날 때마다 그 수를 하나씩 늘린다.

예시가 끝날 때 i는 인스턴스를 닫았지만 공유 변수는 플레이된 총 게임 수를 할당했습니다.그래서 재방송을 할 때 처음 총 회수가 이전 회수와 같았습니다.하지만 각 실행마다 그 값을 나타내기 위해 그 카운트가 필요했다.

수정하기 위해서:

class A3C_Worker(threading.Thread):
    @classmethod
    def reset(cls):
        A3C_Worker.global_shared_total_episodes_across_all_workers = 0

실행 코드보다 더 많은 정보를 얻을 수 있습니다.

A3C_Worker.reset()

이 콜은 클래스 전체에 대한 콜이며 개별 인스턴스가 아닙니다.따라서 지금부터 새로운 에이전트를 시작할 때마다 카운터가 0으로 설정됩니다.

의 방식 「」의 사용def play(self):각 인스턴스에 대해 카운터를 개별적으로 리셋해야 합니다.이것은 계산 부하가 높고 추적도 어렵습니다.

루비에서 나온 것은 클래스 메서드인스턴스 메서드는 첫 번째 파라미터에 의미적 의미가 적용된 함수에 불과하다는 것입니다. 함수는 객체의 메서드로 호출될 때 묵묵히 전달됩니다(즉,).obj.meth()를 참조해 주세요.

일반적으로 이 오브젝트는 인스턴스여야 하지만@classmethod 메서드 데코레이터는 클래스를 통과하도록 규칙을 변경합니다.인스턴스에서 클래스 메서드를 호출할 수 있습니다(이것은 함수일 뿐입니다). 첫 번째 인수는 해당 클래스가 됩니다.

이것은 단지 함수이기 때문에 특정 범위에서 한 번만 선언할 수 있습니다).class정의).따라서 이 경우 Rubyist에게는 놀라운 일이지만 같은 이름의 클래스 메서드와 인스턴스 메서드는 사용할 수 없습니다.

다음 사항을 고려하십시오.

class Foo():
  def foo(x):
    print(x)

요.foo

Foo().foo()
<__main__.Foo instance at 0x7f4dd3e3bc20>

단, 클래스에는 없습니다.

Foo.foo()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unbound method foo() must be called with Foo instance as first argument (got nothing instead)

★★를 추가해 .@classmethod:

class Foo():
  @classmethod
  def foo(x):
    print(x)

인스턴스 호출이 클래스를 통과했습니다.

Foo().foo()
__main__.Foo

클래스에서의 호출과 마찬가지로:

Foo.foo()
__main__.Foo

인스턴스 메서드 및 클래스 메서드에서 첫 번째 인수에 사용하도록 지시하는 것은 규칙뿐입니다. 나는 그것이 단지 논쟁이라는 것을 설명하기 위해 여기 둘 다 사용하지 않았다. 루비에서는 키워드가 있어요.

Ruby와의 대비:

class Foo
  def foo()
    puts "instance method #{self}"
  end
  def self.foo()
    puts "class method #{self}"
  end
end

Foo.foo()
class method Foo

Foo.new.foo()
instance method #<Foo:0x000000020fe018>

Python 클래스 메서드는 장식된 기능일 뿐이며, 동일한 기술을 사용하여 자신만의 데코레이터를 만들 수 있습니다.장식된 방법은 실제 방법을 포장합니다(이 경우).@classmethod추가 클래스 인수를 전달합니다).기본 방법은 여전히 존재하며 숨겨져 있지만 여전히 액세스할 수 있습니다.


각주:클래스와 인스턴스 방식의 이름 충돌로 궁금증이 생겨 이 글을 썼습니다.저는 Python 전문가와는 거리가 멀기 때문에, 이 중 하나라도 틀리면 코멘트를 듣고 싶습니다.

이것은 흥미로운 주제이다.내 견해로는 python class method는 공장이 아닌 싱글톤처럼 동작한다(이것에 의해 생성된 클래스의 인스턴스가 반환된다).싱글톤인 이유는 클래스에 대해 한 번만 생성되지만 모든 인스턴스에서 공유되는 공통 객체가 있기 때문입니다.

여기에 이것을 설명하기 위한 예가 있다.모든 인스턴스는 단일 사전을 참조합니다.제가 알기로는 이것은 공장 패턴이 아닙니다.이것은 아마 비단뱀에게 매우 독특한 것일 것이다.

class M():
 @classmethod
 def m(cls, arg):
     print "arg was",  getattr(cls, "arg" , None),
     cls.arg = arg
     print "arg is" , cls.arg

 M.m(1)   # prints arg was None arg is 1
 M.m(2)   # prints arg was 1 arg is 2
 m1 = M()
 m2 = M() 
 m1.m(3)  # prints arg was 2 arg is 3  
 m2.m(4)  # prints arg was 3 arg is 4 << this breaks the factory pattern theory.
 M.m(5)   # prints arg was 4 arg is 5

나는 몇 번이고 같은 질문을 스스로에게 했다.여기에 있는 사람들은 열심히 설명했지만 IMHO는 Python Documentation의 Class 메서드에 대한 설명입니다.

Static 메서드에 대한 참조도 있습니다.인스턴스 메서드를 이미 알고 있는 사람이 있는 경우(내 추측으로는), 이 답변이 모든 것을 종합하는 마지막 조각이 될 수 있습니다.

이 토픽에 대한 자세한 내용은 다음 문서에서도 확인할 수 있습니다.표준 유형 계층(Instance 메서드 섹션으로 스크롤 다운)

@classmethod는 외부 리소스에서 해당 클래스의 개체를 쉽게 인스턴스화할 때 유용합니다.이치노

import settings

class SomeClass:
    @classmethod
    def from_settings(cls):
        return cls(settings=settings)

    def __init__(self, settings=None):
        if settings is not None:
            self.x = settings['x']
            self.y = settings['y']

그런 다음 다른 파일에서:

from some_package import SomeClass

inst = SomeClass.from_settings()

inst.x 에 액세스 하면, settings ['x']와 같은 값이 됩니다.

물론 클래스는 인스턴스 세트를 정의합니다.그리고 클래스의 메서드는 개별 인스턴스에서 작동합니다.클래스 메서드(및 변수)는 인스턴스 집합과 관련된 다른 정보를 전체적으로 저장하는 장소입니다.

예를 들어, 클래스가 학생 집합을 정의하는 경우 학생이 구성원으로 포함될 수 있는 등급 집합과 같은 것을 정의하는 클래스 변수나 메서드를 원할 수 있습니다.

클래스 메서드를 사용하여 전체 세트에서 작업하기 위한 도구를 정의할 수도 있습니다.예를 들어 Student.all_of_em()은 알려진 모든 학생을 반환할 수 있습니다.인스턴스 집합이 단순한 집합보다 더 많은 구조를 가진 경우 해당 구조에 대해 알기 위한 클래스 메서드를 제공할 수 있습니다.학생들.all_of_em(등급='등급')

이와 같은 기술은 인스턴스 집합의 구성원을 클래스 변수에 뿌리를 둔 데이터 구조에 저장하는 경향이 있습니다.그럼 쓰레기 수거에 방해가 되지 않도록 주의하셔야 합니다.

클래스와 오브젝트 개념은 사물을 정리할 때 매우 유용합니다.한 방법으로 실행할 수 있는 모든 작업은 정적 함수를 사용하여 수행할 수 있습니다.

학생의 세부사항을 유지하기 위해 Students Database 시스템을 구축하는 시나리오를 생각해 보십시오.학생, 교사, 교직원들에 대한 자세한 정보가 필요합니다.수수료, 급여, 점수 등을 계산하는 함수를 구축해야 합니다.수수료와 마크는 학생에게만 적용되며, 급여는 직원과 교사에게만 적용됩니다.따라서 모든 유형의 사용자에 대해 별도의 클래스를 만들면 코드가 정리됩니다.

언급URL : https://stackoverflow.com/questions/38238/what-is-the-purpose-of-class-methods

반응형