Как создать класс, в котором создание экземпляров происходит только при соблюдении определенных условий? - PullRequest
1 голос
/ 16 июня 2019

Допустим, у меня есть этот класс:

class Person:
    def __init__(self, name):
        self.name = name

Если я хочу создать экземпляр Person Я могу сделать:

me = Person("António")

Но что, если я хочу создать экземпляр * 1008?* если name имеет тип str?
Я пробовал это:

class Person:
    def __init__(self, name):
        if type(name) == str:
            self.name = name

Но тогда, когда я делаю:

me = Person("António")
print(me.name)

you = Person(1)
print(you.name)

Я получаю это:

enter image description here

Таким образом, все, что происходит:

  • Если name равно str, экземпляр имеет метод .name
  • Если name не str, у экземпляра нет .name метода

Но что я на самом деле хочу, так это остановить все экземпляры вместе, если имя не является str.
Другими словами, я хочу, чтобы было невозможно создать объект из класса Person с не str name.

Как я могу это сделать?

Ответы [ 3 ]

1 голос
/ 16 июня 2019

Вы можете использовать фабрику, которая проверяет параметры и возвращает объект Person, если все в порядке или выдает ошибку:

может быть, что-то в строке этого:

class PersonNameError(Exception):
    pass

class Person:
    def __init__(self):
        self.name = None

def person_from_name(name: str) -> Person:
    """Person factory that checks if the parameter name is valid
    returns a Person object if it is, or raises an error without 
    creating an instance of Person if not.
    """
    if isinstance(name, str):
        p = Person()
        p.name = name
        return p
    raise PersonNameError('a name must be a string')

p = person_from_name('Antonio') 

Принимая во внимание:

p = person_from_name(123)   # <-- parameter name is not a string

выдает исключение:

PersonNameError                           Traceback (most recent call last)
<ipython-input-41-a23e22774881> in <module>
     14 
     15 p = person_from_name('Antonio')
---> 16 p = person_from_name(123)

<ipython-input-41-a23e22774881> in person_from_name(name)
     11         p.name = name
     12         return p
---> 13     raise PersonNameError('a name must be a string')
     14 
     15 p = person_from_name('Antonio')

PersonNameError: a name must be a string
0 голосов
/ 16 июня 2019

Вы должны использовать factory design pattern. Вы можете прочитать больше об этом здесь . Проще говоря:

Создать класс / метод, который будет проверять условия и возвращать новый экземпляр класса, только если эти условия будут выполнены.

0 голосов
/ 16 июня 2019

Как насчет:

class Person:
    def __init__(self, name):
        if type(name) == str:
            self.name = name
        else: 
            raise Exception("name attribute should be a string")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...