python 함수 전참 전달dict/list/set 등 유형의 문제

전참 시 가변 대상을 전달하고, 실제 업로드는 메모리 주소를 가리키는 바늘/인용


이 제목은 나의 결론이자 내가 프로젝트를 하는 과정에서 찾아낸 것이다.C를 배운 사람들은 모두 함수 전삼은 값을 전할 수도 있고 바늘을 전할 수도 있다는 것을 안다.바늘의 장점은 여기에서 더 이상 군더더기 말하지 않는다.
먼저 코드를 올려 효과를 보십시오.

def trans(var):
  return var

source = {1: 1}
dist = trans(source)
source[2] = 2
print(source)
print(dist)
실행 결과:
{1: 1, 2:2}
{1: 1, 2:2}
소스가 바뀌었을 때,dist도 따라서 바뀌는 것을 볼 수 있다.그 이유는 소스가 가변 대상이고 매개 변수를 전달할 때 인용 (C의 지침) 을 전달하기 때문이다.dist와source는 모두 같은 메모리 공간을 가리킨다.소스[2]=2를 실행할 때 메모리 공간에 대한 데이터의 변경이기 때문에dist도 이에 따라 변화한다.
무슨 작용이 있을까요?장면이 많을 텐데 본인의 경력이 얕아서 전형적인 장면을 생각하지 못하고 자신의 프로젝트를 예로 들겠습니다.
프로젝트에서 나는 클래스를 정의했다. 이 클래스는 읽기와 쓰기에 사용되고 json 설정을 저장합니다. 클라이언트는 설정을 읽을 수 있습니다. 저장된 설정이 클라이언트가 읽는 설정을 포함하지 않을 때 장치에서 읽을 수 있습니다.
나는 이 종류의 실례를 여러 개의 대상으로 바꾸어 여러 개의 클라이언트에 대응해야 한다.그러나 나는 저장된 설정이 공공적이길 바란다. 이렇게 하면 낯선 설정에 대해 모든 클라이언트가 요청하지 않을 때 장치에서 읽어야 한다.
처음에 나는 이렇게 썼다.

global dataset
dataset = {}

class Config(object):
  def __init__(self, device_url):
    self.device_url = device_url
  
  def get_config(self, key):
    global dataset
    
    if key in dataset:
      return dataset.get(key)
    else:
      #  device_url , value
      dataset[key] = value
      return value
    
  def other_func(self):
    #  , device_url 
    pass

이후에 나는 여러 개의 공공 설정이 필요했고 심지어 1000부 이상에 도달해야 했다. 분명히 전체 변수가 만족스럽지 못했다.메모리를 함께 사용해야 하기 때문에 나는 가변 대상을 전달하고 코드를 이렇게 바꿨다.

class Config(object):
  
  def __init__(self, dataset, device_url):    #  dataset
    self.dataset = dataset
    self.device_url = device_url
  
  def get_config(self, key):    
    if key in self.dataset:
      return self.dataset.get(key)
    else:
      #  device_url , value
      self.dataset[key] = value    #  dataset , dataset 
      return value
    
  def other_func(self):
    #  , device_url 
    pass


목록, 사전, 집합이 반드시 가변 대상은 아니다


인터넷에는 목록, 사전, 집합이 가변 대상이라는 자료가 한 무더기 있는데, 이 말은 완전히 정확하지 않다.{} [] set (,) 상수는 가변 객체가 아닙니다.
위의 Config 클래스는 인스턴스화할 때 {} 를 전달하면 구성을 공유할 수 없습니다.

config1 = Config({})
config2 = Config({})
config1.dataset[1] = 1
print(repr(config1.dataset))
print(repr(config2,dataset))

위의 실행 결과는
'{1: 1}'
'None'
하면, 만약, 만약...

share_var = {}
config1 = Config(share_var)
config2 = Config(share_var)
config1.dataset[1] = 1
print(repr(config1.dataset))
print(repr(config2,dataset))

실행 결과는 다음과 같습니다.
'{1: 1}'
'{1: 1}'
share_var는 가변 객체이지만 {}는 가변 객체입니다. share_var는 {} 값과 같습니다.
더 깊이 이해하려면python의 명명 공간을 이해해야 한다.

가변 대상 매개 변수를 전달하고 전달하는 데 주의해야 할 일

  • 인용/바늘을 전달하고 대응하는 메모리 공간을 조작하지 않으면 전참할 때 사전, 목록, 집합, 클래스 또는 클래스의 실례화 대상 등 유형을 전달하지 않도록 주의하십시오
  • 가변 대상의 매개 변수를 전달할 때 상수 {}[]set(,)를 전달하지 않도록 주의하십시오. 가장 좋은 것은 전참 전에 변수를 지불하고 전참할 때 이 변수를 전달하는 것입니다
  • 원리를 알게 되면 직접 전상량까지는 아니지만 다음과 같은 상황이 발생할 수 있다.
    
    def func1(mutable_object, flag):
      if flag:
        return mutable_object
      else:
        return {}
    
    def func2(mutable_object):
      # something to do with mutable_object
      pass
    
    func2(func1(mutable_object, False)) #  func1(mutable_object, False) {}, 
    
    
    이는python 함수 전참 전달dict/list/set 등 유형에 대한 상세한 문제에 관한 글을 소개합니다. 더 많은python 함수 전참 전달 내용은 저희 이전의 글을 검색하거나 아래의 관련 글을 계속 찾아보세요. 앞으로 많은 응원 부탁드립니다!

    좋은 웹페이지 즐겨찾기