1) Так называемая проблема «Mutable Default Argument» - это, в общем, специальный пример, демонстрирующий, что: «Все функции с этой проблемой также страдают от аналогичной проблемы побочного эффекта от фактического параметра». Это противоречит правилам
Пример:
def foo(a=[]): # the same problematic function
a.append(5)
return a
>>> somevar = [1, 2] # an example without a default parameter
>>> foo(somevar)
[1, 2, 5]
>>> somevar
[1, 2, 5] # usually expected [1, 2]
Решение: копия Совершенно безопасным решением является copy
или deepcopy
входной сигнал сначала, а затем делать все с копией.
def foo(a=[]):
a = a[:] # a copy
a.append(5)
return a # or everything safe by one line: "return a + [5]"
Многие встроенные изменяемые типы имеют метод копирования, такой как some_dict.copy()
или some_set.copy()
, или могут быть скопированы легко, как somelist[:]
или list(some_list)
, Каждый объект также может быть скопирован с помощью copy.copy(any_object)
или более тщательным с помощью copy.deepcopy()
(последний полезен, если изменяемый объект состоит из изменяемых объектов). Некоторые объекты основаны на побочных эффектах, таких как «файл», и не могут быть осмысленно воспроизведены копией. копирование
Пример проблемы для аналогичного вопроса SO
class Test(object): # the original problematic class
def __init__(self, var1=[]):
self._var1 = var1
somevar = [1, 2] # an example without a default parameter
t1 = Test(somevar)
t2 = Test(somevar)
t1._var1.append([1])
print somevar # [1, 2, [1]] but usually expected [1, 2]
print t2._var1 # [1, 2, [1]] but usually expected [1, 2]
Он не должен быть ни сохранен ни в одном ] public экземпляра, возвращаемого этой функцией. (Предполагая, что атрибуты private экземпляра не должны быть изменены извне этого класса или подкласса по соглашению, т. Е. _var1
является частным атрибутом)
Заключение: Параметры входных параметров shouldn 'изменяются на месте (мутированные), и они не должны быть привязаны к объекту, возвращаемому функцией. (Если мы предпочитаем программирование без побочных эффектов, которые настоятельно рекомендуются, см. Wiki о «побочном эффекте» (первые два абзаца имеют смысл в этом контексте.).)
2) Только если побочный эффект на фактический параметр требуется, но нежелателен по параметру по умолчанию, тогда полезным решением является def ...(var1=None):
if var1 is None:
var1 = []
Подробнее ..
3) В некоторых случаях используется изменчивое поведение параметров по умолчанию .
export PGPASSWORD='password'; psql -h 'server name' -U 'user name' -d 'base name' -c 'command'
с командой команда sql, такая как "select * from schema.table"
export PGPASSWORD='password'
psql -h 'server name' -U 'user name' -d 'base name' \
-c 'command' (eg. "select * from schema.table")
В Windows:
C:\>set PGPASSWORD=pass
C:\>psql -d database -U user
Готов
Или в одной строке,
set PGPASSWORD=pass&& psql -d database -U user
Обратите внимание на недостаток места перед & amp; & amp; & amp; !
Я предпочитаю передавать URL-адрес в psql:
psql "postgresql://$DB_USER:$DB_PWD@$DB_SERVER/$DB_NAME"
Это дает мне право называть мои переменные среды по своему усмотрению и позволяет избежать создания ненужных файлов.
требуется libpq
. Документацию можно найти здесь здесь
Это можно сделать, создав файл .pgpass
в домашнем каталоге пользователя (Linux). .pgpass
формат файла:
<databaseip>:<port>:<databasename>:<dbusername>:<password>
Вместо деталей вы можете использовать wild card *
.
Скажем, я хотел запустить tmp.sql
без запроса пароля ,
С помощью следующего кода вы можете в * .sh файле
echo "192.168.1.1:*:*:postgres:postgrespwd" > $HOME/.pgpass
echo "` chmod 0600 $HOME/.pgpass `"
echo " ` psql -h 192.168.1.1 -p 5432 -U postgres postgres -f tmp.sql `
Установите переменную среды PGPASSWORD внутри скрипта перед вызовом psql
PGPASSWORD=pass1234 psql -U MyUsername myDatabaseName
. Для справки см. http://www.postgresql.org/docs/current/static/libpq-envars .html
Редактировать
Поскольку Postgres 9.2 также имеет возможность указать строку соединения или URI , которая может содержать имя пользователя и пароль.
Использование этого является угрозой безопасности, поскольку пароль отображается в виде обычного текста при просмотре командной строки текущего процесса, например. используя ps
(Linux), ProcessExplorer (Windows) или аналогичные инструменты другими пользователями.
См. также этот вопрос в Администраторы базы данных
space
в командной строке перед первым символом, и команда не будет сохранена в истории bash. Работает для ubuntu / bash.
– baldr
15 October 2016 в 18:01
docker run -e PGPASSWORD="$(pbpaste)" --rm postgres psql -h www.example.com dbname username -c 'SELECT * FROM table;'
– Bilal Akil
23 November 2017 в 05:34
PGPASSWORD='password' psql ....
, которая также имеет преимущество в том, что переменная недоступна после выполнения команды. – Garrett 13 January 2016 в 22:36export PGPASSWORD=YourNewPassword
работал для меня по другим вариантам. – Mikeumus 4 April 2016 в 04:38export PGPASSWORD
звучит как действительно плохая идея – hasen 28 August 2017 в 10:38