Вызов параметризованного конструктора в enum singleton?

Вот краткое описание способов вызова внешних программ и преимуществ и недостатков каждого из них:

  1. os.system("some_command with args") передает команду и аргументы в оболочку вашей системы. Это хорошо, потому что вы можете запускать сразу несколько команд таким образом и настраивать каналы и перенаправление ввода / вывода. Например:
    os.system("some_command < input_file | another_command > output_file")  
    
    Однако, хотя это удобно, вы должны вручную обрабатывать экранирование символов оболочки, таких как пробелы и т. Д. С другой стороны, это также позволяет запускать команды, которые являются просто командами оболочки, а не фактически внешними программами , См. документацию .
  2. stream = os.popen("some_command with args") будет делать то же самое, что и os.system, за исключением того, что он дает файл-подобный объект, который вы можете использовать для доступа к стандартному вводу / выводу для этого процесса. Есть еще 3 варианта popen, которые все обрабатывают i / o немного по-другому. Если вы передаете все как строку, ваша команда передается в оболочку; если вы передадите их в список, то вам не нужно беспокоиться о том, чтобы избежать чего-либо. См. документацию .
  3. Класс Popen модуля subprocess. Это предназначено для замены os.popen, но имеет недостаток в том, что он немного усложняется благодаря тому, что он настолько всеобъемлющий. Например, вы могли бы сказать:
    print subprocess.Popen("echo Hello World", shell=True, stdout=subprocess.PIPE).stdout.read()
    
    вместо:
    print os.popen("echo Hello World").read()
    
    , но хорошо иметь все варианты там в одном унифицированном классе вместо 4 различных функций popen. См. документацию .
  4. Функция call из модуля subprocess. Это в основном так же, как класс Popen, и принимает все те же аргументы, но он просто ждет, пока команда не завершится, и вы получите код возврата. Например:
    return_code = subprocess.call("echo Hello World", shell=True)  
    
    См. документацию .
  5. Если вы используете Python 3.5 или новее, вы можете использовать новую функцию subprocess.run , что очень похоже на выше, но еще более гибкое и возвращает объект CompletedProcess , когда команда завершает выполнение.
  6. В модуле os также есть все fork / exec / spawn, которые у вас были бы в программе на C, но я не рекомендую использовать их напрямую.

Возможно, модуль subprocess - это то, что вы используете.

Наконец, имейте в виду, что для всех методов, в которых вы передаете окончательную команду для выполнения оболочкой в ​​виде строки, и вы несете ответственность за ее выход из нее. Имеются серьезные последствия для безопасности, если какая-либо часть передаваемой строки не может быть полностью доверена. Например, если пользователь вводит какую-либо / любую часть строки. Если вы не уверены, используйте эти методы только с константами. Чтобы дать вам намек на последствия, рассмотрите этот код:

print subprocess.Popen("echo %s " % user_input, stdout=PIPE).stdout.read()

и представьте, что пользователь вводит «моя мама не любила меня & amp; & amp; rm -rf /".

0
задан manish 4 March 2019 в 15:34
поделиться

3 ответа

Как правило, вы можете использовать тип класса, а не тип enum. Перечисления должны быть статичными и окончательными. Идея конструктора enum заключается в том, чтобы инкапсулировать несколько значений, чтобы их можно было использовать после установки только одного типа enum.

public enum Vehicle {
    CAR(4, 2),
    TRUCK(6, 20);

    private Integer numOfTyres;
    private Integer maxWeight;

    Vehicle(Integer numOfTyres, Integer maxWeight) {
        this.numOfTyres = numOfTyres;
        this.maxWeight = maxWeight;
        System.out.println("Number of Tyres = " + numOfTyres);
        System.out.println("Max weight = " + maxWeight);
    }


    public Integer getMaxWeight() {
         return maxWeight;
    }

    public Integer getNumberOfTyres() {
        return numOfTyres;
    }

}


public class Main {
    public static void main(String s[]) {
        Vehicle.CAR.getNumberOfTyres();

        for (Vehicle v : Vehicle.values()) {
            System.out.println();

            StringBuilder sb = new StringBuilder();
            sb.append("Vehicle ");
            sb.append(v.name());
            sb.append(" has ");
            sb.append(v.getNumberOfTyres());
            sb.append(" number of tyres and ");
            sb.append(v.getMaxWeight());
            sb.append(" max weight ");


            System.out.println("-----------------");
            System.out.println(sb.toString());
            System.out.println("-----------------");
        }

    }

}
0
ответ дан Pulszar 4 March 2019 в 15:34
поделиться

Как вы, вероятно, знаете, конструктор для типа enum должен быть закрытым или закрытым доступом.

Он вызывается автоматически и создает константы, которые определены в начале тела enum.

Вы не можете вызвать конструктор enum самостоятельно.

Вот несколько примеров, которые могут быть полезны.

public enum MySingleton {
    // if you have multiple constants here - it's not Singleton
    INSTANCE;

    // if you need to provide some info to your INSTANCE,
    // you can add params to its methods
    public void someMethod(String value) {
        System.out.println("inside someMethod, value is " +value);
    }
}

Если вам нужно, чтобы экземпляр имел некоторое состояние, вы можете добавить поля и конструктор:

public enum MySingleton {
    INSTANCE("Hello");

    private String message;

    MySingleton(String msg) {
        this.message = msg;
    }

    // you can even have getter/setter for it
    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

Пример основного метода:

public static void main(String[] args) {
    System.out.println(MySingleton.INSTANCE.getMessage()); // prints Hello

    MySingleton.INSTANCE.setMessage("Bye");

    System.out.println(MySingleton .INSTANCE.getMessage()); // prints Bye
}
0
ответ дан john 4 March 2019 в 15:34
поделиться

У вас может быть что-то подобное

    enum C1 {
        WITH_PARAM("value"),
        EMPTY();

        private String value;
        C1(String s) {
            System.out.println("with param = " +s);
            value=s;
        }
        C1() {
            System.out.println("without param");
        }
        public void g() {
            System.out.println("inside g, value is "+value);
        }
    }

        public static void main(String s[]) {
            C1.EMPTY.g();
            C1.WITH_PARAM.g();

        }
.
0
ответ дан Alexander Pavlov 4 March 2019 в 15:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: