Mam klasę Python, która zawiera wszystkie regiony AWS. Napisałem metodę klasy, która zwróci mi listę wszystkich regionów. Czy istnieje lepszy sposób zwrotu wszystkich wartości zmiennych klasowych, więc nie muszę twardego kodu wszystkich wartości w instrukcji zwrotnej, tak jak robię w poniższym przykładzie?

class AwsRegion():
    '''
    Class to define AWS Regions
    '''
    OHIO = 'us-east-2'
    NORTH_VIRGINIA = 'us-east-1'
    NORTH_CALIFORNIA = 'us-west-1'
    OREGON = 'us-west-2'
    MUMBAI = 'ap-south-1'
    SEOUL = 'ap-northeast-2'
    SINGAPORE = 'ap-southeast-1'
    SYDNEY = 'ap-southeast-2'
    TOKYO = 'ap-northeast-1'
    FRANKFURT = 'eu-central-1'
    IRELAND = 'eu-west-1'
    LONDON = 'eu-west-2'
    SAO_PAULO = 'sa-east-1'

    @classmethod
    def all(cls, ):
        return [AwsRegion.OHIO, AwsRegion.NORTH_VIRGINIA, AwsRegion.NORTH_CALIFORNIA, AwsRegion.OREGON, \
            AwsRegion.MUMBAI, AwsRegion.SEOUL, AwsRegion.SINGAPORE, AwsRegion.SYDNEY, AwsRegion.TOKYO, \
            AwsRegion.FRANKFURT, AwsRegion.IRELAND, AwsRegion.LONDON, AwsRegion.SAO_PAULO]
4
Varun Verma 28 czerwiec 2017, 00:15

3 odpowiedzi

Najlepsza odpowiedź

W takim przypadku możesz wyliczyć wszystkie atrybuty klasy, które są wielkie; Używałbym vars() Funkcja, aby uzyskać dostęp do przestrzeń nazw klasy:

@classmethod
def all(cls):
    return [value for name, value in vars(cls).items() if name.isupper()]

Próbny:

>>> class AwsRegion():
...     '''
...     Class to define AWS Regions
...     '''
...     OHIO = 'us-east-2'
...     NORTH_VIRGINIA = 'us-east-1'
...     NORTH_CALIFORNIA = 'us-west-1'
...     OREGON = 'us-west-2'
...     MUMBAI = 'ap-south-1'
...     SEOUL = 'ap-northeast-2'
...     SINGAPORE = 'ap-southeast-1'
...     SYDNEY = 'ap-southeast-2'
...     TOKYO = 'ap-northeast-1'
...     FRANKFURT = 'eu-central-1'
...     IRELAND = 'eu-west-1'
...     LONDON = 'eu-west-2'
...     SAO_PAULO = 'sa-east-1'
...     @classmethod
...     def all(cls):
...         return [value for name, value in vars(cls).items() if name.isupper()]
...
>>> AwsRegion.all()
['us-east-2', 'us-east-1', 'us-west-1', 'us-west-2', 'ap-south-1', 'ap-northeast-2', 'ap-southeast-1', 'ap-southeast-2', 'ap-northeast-1', 'eu-central-1', 'eu-west-1', 'eu-west-2', 'sa-east-1']
2
Martijn Pieters 27 czerwiec 2017, 22:11

Wygląda na to, co możesz zrobić przypadkowo tworzyć {x0}} Typ.

Jeśli klasa AwsRegion jest używana tylko do przechowywania tych wartości (nie wiele innych złożonych zachowań), spróbuj zrobić podklasę Enum. Dałoby ci to garść ładnych metod bez konieczności odtworzenia tego wszystkiego i sprawi, że twój kod jest wyraźniejszy dla innych, którzy wiedzą, jakie są łączone typy.

from enum import Enum

class AwsRegion2(Enum):
    OHIO = 'us-east-2'
    NORTH_VIRGINIA = 'us-east-1'
    NORTH_CALIFORNIA = 'us-west-1'
    OREGON = 'us-west-2'
    MUMBAI = 'ap-south-1'
    SEOUL = 'ap-northeast-2'
    SINGAPORE = 'ap-southeast-1'
    SYDNEY = 'ap-southeast-2'
    TOKYO = 'ap-northeast-1'
    FRANKFURT = 'eu-central-1'
    IRELAND = 'eu-west-1'
    LONDON = 'eu-west-2'
    SAO_PAULO = 'sa-east-1'


print(list(AwsRegion2))
1
Nathaniel Rivera Saul 27 czerwiec 2017, 22:25

Jako ogólne odniesienie można uzyskać atrybuty dowolnej klasy przez następujący sposób.
Wybierz W zależności od potrzeb:

__dict__:

zwróci dyktaty wszystkich atrybutów klasy . Jest to zazwyczaj to, czego potrzebujesz.

my_obj = MyClass()
attributes = my_obj.__dict__

vars():

ten sam wynik jak __dict__, ale używając tego, a nie jest uważany za najlepszą praktykę.

my_obj = MyClass()
attributes = vars(my_obj)

dir():

Zwróci wszystkie atrybuty klasy , w tym te, które nie są wykonane przez ciebie, ale są dziedziczone z object.

my_obj = MyClass()
attributes = dir(my_obj)

W twoim przypadku przy użyciu vars() będzie działać w porządku, jak pokazał Martijn Pieters w jego Odpowiedź.

3
Barm 17 luty 2020, 12:46