2016-04-08 16 views
0

AWS sarmalayıcı sınıfı için S3 üzerinde bir hedef belirlemek üzere özellik sınıfı kullanıyorum. Sadece bir infile de ayarlanmışsa hedefi belirlemelidir. (En iyi çözümün, bu sınıfın, bir şey yerine iki şeyi iyi bir şekilde yapmaya çalıştığı için ayrılması olacağını fark ettim).@property, bir şekilde yinelemeli aramayı başlatıyor?

Yine de, bu yinelenen yığının taşmasına neden olan şeyin ne olduğunu merak ediyorum.

class S3Loads(PrettyStr): 
    def __init__(self, 
       infile=None, 
       s3_destination=None, 
       s3_bucket=config3.S3_BUCKET, 
       s3_credentials=config3.S3_INFO, 
       database_credentials=config3.REDSHIFT_POSTGRES_INFO_PROD): 
     """ 
     This class automates the upload of a file to AWS S3. 

     :param infile: A gzipped csv file 
     :param s3_destination: The path to the desired folder on S3. The file 
     will be named by joining the s3_destination and the infile name. 
     :param s3_bucket: The name of the bucket on S3 

     :return: None, but will write out to logging file. 
     """ 
     self.infile = infile 
     self.s3_destination = s3_destination 
     self.bucket_name = s3_bucket 
     self.s3_creds = s3_credentials 
     self.database_credentials = database_credentials 

    @property 
    def s3_destination(self): 
     return self.s3_destination 
    # TODO This is kicking off a recursive call, find out why 
    @s3_destination.setter 
    def s3_destination(self, s3_destination): 
     if self.infile: 
      if config3.SYSTEM == 'OSX': 
       self.s3_destination = path.join(
       s3_destination, 
       self.infile.split('/')[-1] 
       ) 
      elif config3.SYSTEM == 'Windows': 
       self.s3_destination = path.join(
       s3_destination, 
       self.infile.split('\\')[-1] 
       ) 
     else: 
      logging.warning('S3 Destination is being set to "None" due to ' 
          'no infile being set. Please set an infile ' 
          'and then set the S3 Destination.') 
      self.s3_destination = None 

Ve bu kapalı tekme birim testleri şunlardır::

def test_setting_s3_destination_without_infile_set_it_to_none(self): 
     s3 = aws_utils.S3Loads() 
     def test_func(): 
      s3.s3_destination = 'Some destination' 
     self.assertIsNone(s3.s3_destination) 

    def test_can_set_s3_destination_with_infile_specified(self): 
     s3 = aws_utils.S3Loads() 
     s3.infile='testfile.txt' 
     s3.destination='testloads/test1' 
     self.assertEqual(s3.destination, 'testloads/test1/testfile.txt') 

Ben özyinelemeye neyin neden olduğunu merak ettim İşte benim sınıfının ilgili kısmıdır.

cevap

1

Python her zaman self.s3_destination ile karşılaşır, s3_destination işlevi çağrılır.

class S3Loads(PrettyStr): 
    def __init__(self,...) 
     ... 
     self._s3_destination = s3_destination 

    @property 
    def s3_destination(self): 
     return self._s3_destination 


    @s3_destination.setter 
    def s3_destination(self, value): 
     if self.infile: 
      if config3.SYSTEM == 'OSX': 
       self._s3_destination = path.join(
       value, 
       self.infile.split('/')[-1] 
       ) 
      elif config3.SYSTEM == 'Windows': 
       self._s3_destination = path.join(
       value, 
       self.infile.split('\\')[-1] 
       ) 
     else: 
      logging.warning('S3 Destination is being set to "None" due to ' 
          'no infile being set. Please set an infile ' 
          'and then set the S3 Destination.') 
      self._s3_destination = None 
: dönüş değeri beri self.s3_destination referanslar mülkiyet, s3_destination fonksiyon sonsuza ...

@property 
def s3_destination(self): 
    return self.s3_destination 

Bunu düzeltmek için standart yolu özel niteliğini self._s3_destination kullanmaktır, yinelemeli olarak adlandırılır

+0

Özel özniteliğin neden diğerinin çalışmadığını açıklar mısınız? Doğru olarak hatırlarsam, tek bir alt çizgi – flybonzai

+1

Managling'i başlatmaz. Bir özelliğin "özel" olduğunu belirtmek için tek bir alt çizgi kullanmak yalnızca bir kuraldır. Python'un kendisi, alt-çizilmemiş bir öznitelikten farklı bir şekilde davranmaz. (Siz haklısınız - tam tersine, çift alt çizgiler, adlandırma işlemini tetikler.) İkinci bir özniteliğe ("özel" olsun ya da olmasın) gerek duymanızın sebebi, "kendi" tarafından döndürülen ** temel değerinin ** saklanmasıdır. .s3_destination'. Aksi halde, keşfettiğiniz gibi, özellik işlevi çağrısının ("self.s3_destination" tarafından tetiklenen) temel değere erişmesini engellemenin hiçbir yolu yoktur. – unutbu

İlgili konular