Я работал над одной и той же проблемой в течение полудня и, наконец, понял это.
Для неявного FTP TLS / SSL (defualt port 990) наша клиентская программа должна создать TLS / SSL соединение сразу после создания сокета. Но класс python FTP_TLS
не перезагружает функцию подключения из класса FTP. Мы должны исправить это:
class tyFTP(ftplib.FTP_TLS):
def __init__(self,
host='',
user='',
passwd='',
acct='',
keyfile=None,
certfile=None,
timeout=60):
ftplib.FTP_TLS.__init__(self,
host=host,
user=user,
passwd=passwd,
acct=acct,
keyfile=keyfile,
certfile=certfile,
timeout=timeout)
def connect(self, host='', port=0, timeout=-999):
"""Connect to host. Arguments are:
- host: hostname to connect to (string, default previous host)
- port: port to connect to (integer, default previous port)
"""
if host != '':
self.host = host
if port > 0:
self.port = port
if timeout != -999:
self.timeout = timeout
try:
self.sock = socket.create_connection((self.host, self.port), self.timeout)
self.af = self.sock.family
# add this line!!!
self.sock = ssl.wrap_socket(self.sock,
self.keyfile,
self.certfile,
ssl_version=ssl.PROTOCOL_TLSv1)
# add end
self.file = self.sock.makefile('rb')
self.welcome = self.getresp()
except Exception as e:
print(e)
return self.welcome
Этот производный класс перезагружает функцию подключения и создает оболочку вокруг сокета для TLS. После успешного подключения и входа на FTP-сервер вам необходимо вызвать: FTP_TLS.prot_p()
перед выполнением любой команды FTP!
Надеюсь, это поможет ^ _ ^
Вместо использования
import os
dirname = os.path.dirname(__file__)
filename = os.path.join(dirname, 'relative/path/to/file/you/want')
, как в принятом ответе, было бы более надежно использовать:
import inspect
import os
dirname = os.path.dirname(os.path.abspath(inspect.stack()[0][1]))
filename = os.path.join(dirname, 'relative/path/to/file/you/want')
, поскольку использование __file__ вернет файл, из которого модуль был загружен, если он был загружен из файла, поэтому, если файл со сценарием вызывается из другого места, возвращаемый каталог будет неправильным.
Эти ответы дают более подробную информацию: https://stackoverflow.com/a/31867043/5542253 и https://stackoverflow.com/a/50502/5542253
Этот код вернет абсолютный путь к основному скрипту.
import os
def whereAmI():
return os.path.dirname(os.path.realpath(__import__("__main__").__file__))
Это будет работать даже в модуле.
sys.modules['__main__'].__file__
.
– Martijn Pieters♦
12 May 2018 в 19:05
Привет, прежде всего, вы должны понимать функции os.path.abspath (path) и os.path.relpath (path)
Короче os.path.abspath (path) делает относительный путь к абсолютный путь. И если предоставленный путь сам по себе является абсолютным путем, то функция возвращает тот же путь.
аналогично os.path.relpath (path) делает абсолютный путь к относительному пути. И если предоставленный путь сам по себе является относительным путем, функция возвращает один и тот же путь.
Ниже приведен пример, который вы можете правильно понимать в приведенной выше концепции :
предположим, что у меня есть файл input_file_list.txt, который содержит список входных файлов, которые будут обрабатываться моим скриптом python.
D: \ conc \ input1.dic
D: \ conc \ input2 .dic
D: \ Copyioconc \ input_file_list.txt
Если вы видите выше структуру папок, input_file_list.txt присутствует в папке Copyofconc, а файлы, которые должны обрабатываться скриптом python, присутствует в папке conc
Но содержимое файла input_file_list.txt выглядит так:
.. \ conc \ input1.dic
.. \ conc \ input2.dic
И мой скрипт python присутствует в D: диске.
И относительный путь, указанный в файле input_file_list.txt, относится к пути input_file_list.txt file.
Итак, когда скрипт python должен выполнить текущий рабочий каталог (используйте os.getcwd (), чтобы получить pa th)
Поскольку мой относительный путь относится к input_file_list.txt, то есть «D: \ Copyofconc», мне нужно изменить текущий рабочий каталог на «D: \ Copyofconc».
Поэтому мне нужно использовать os.chdir ('D: \ Copyofconc'), поэтому текущий рабочий каталог должен быть «D: \ Copyofconc».
Теперь, чтобы получить файлы input1.dic и input2 .dic, я прочитаю строки «.. \ conc \ input1.dic», затем будет использовать команду
input1_path = os.path.abspath ('.. \ conc \ input1.dic') ( для изменения относительного пути к абсолютному пути. Здесь в качестве текущего рабочего каталога находится «D: \ Copyofconc», к файлу «. \ Conc \ input1.dic» следует обращаться относительно «D: \ Copyofconc»)
, поэтому input1_path должен быть «D: \ конц \ input1.dic "
Как упоминалось в принятом ответе
import os
dir = os.path.dirname(__file__)
filename = os.path.join(dir, '/relative/path/to/file/you/want')
, я просто хочу добавить, что
последняя строка не может начинаться с обратного слэша, infact no string should включая обратную косую черту
blockquote>Это должно быть что-то вроде
import os dir = os.path.dirname(__file__) filename = os.path.join(dir, 'relative','path','to','file','you','want')
. В некоторых случаях принятый ответ может вводить в заблуждение, обратитесь к this link для деталей
os.path.join
, лучше, потому что он соединяет их с разделителем OS-специфики.
– Farshid T
4 September 2016 в 09:16
'/relative/path...'
не является относительным путем. Это намеренно?
– steveire
13 February 2018 в 13:24
os.path.join()
. Остается предпочтение использовать отдельные строки для каждого элемента пути по сравнению с жесткой кодировкой разделителя путей.
– Martijn Pieters♦
12 May 2018 в 18:57
Рассмотрим мой код:
import os
def readFile(filename):
filehandle = open(filename)
print filehandle.read()
filehandle.close()
fileDir = os.path.dirname(os.path.realpath('__file__'))
print fileDir
#For accessing the file in the same folder
filename = "same.txt"
readFile(filename)
#For accessing the file in a folder contained in the current folder
filename = os.path.join(fileDir, 'Folder1.1/same.txt')
readFile(filename)
#For accessing the file in the parent folder of the current folder
filename = os.path.join(fileDir, '../same.txt')
readFile(filename)
#For accessing the file inside a sibling folder.
filename = os.path.join(fileDir, '../Folder2/same.txt')
filename = os.path.abspath(os.path.realpath(filename))
print filename
readFile(filename)
Альтернатива, которая работает для меня:
this_dir = os.path.dirname(__file__)
filename = os.path.realpath("{0}/relative/file.path".format(this_dir))
Я не уверен, что это относится к некоторым из старых версий, но я считаю, что Python 3.3 имеет поддержку родного пути.
Например, следующий код должен создать текстовый файл в той же папке как скрипт python:
open("text_file_name.txt", "w+t")
(обратите внимание, что в начале это не должно быть прямой или обратной косой черты, если это относительный путь)
См. sys.path . Инициализированный при запуске программы, первым элементом этого списка, путь [0], является каталог, содержащий скрипт, который использовался для вызова интерпретатора Python.
Используйте этот путь в качестве корневой папки, из которой вы применяете свой относительный путь
>>> import sys
>>> import os.path
>>> sys.path[0]
'C:\\Python25\\Lib\\idlelib'
>>> os.path.relpath(sys.path[0], "path_to_libs") # if you have python 2.6
>>> os.path.join(sys.path[0], "path_to_libs")
'C:\\Python25\\Lib\\idlelib\\path_to_libs'
sys.path[0]
не всегда устанавливается в родительский каталог. Код Python может быть вызван с помощью -c
или -m
или через встроенный интерпретатор, и в этот момент sys.path[0]
устанавливается совсем другое.
– Martijn Pieters♦
12 May 2018 в 18:58
вам нужно os.path.realpath
(образец ниже добавляет родительский каталог к вашему пути)
import sys,os
sys.path.append(os.path.realpath('..'))
os.path.dirname(__file__)
дал мне пустую строку. Это сработало отлично.
– Darragh Enright
21 February 2014 в 12:51
os.path.realpath('..')
предоставляет родительский каталог текущего рабочего каталога . Обычно не , что вы хотите.
– Martijn Pieters♦
12 May 2018 в 18:55
Что сработало для меня, это использовать sys.path.insert
. Затем я указал каталог, в котором мне нужно было идти. Например, мне просто нужно было перейти в один каталог.
import sys
sys.path.insert(0, '../')
Сейчас 2018, и Python уже давно эволюционировали __future__
. Итак, как насчет использования удивительного pathlib
, следующего с Python 3.4, для выполнения задачи вместо того, чтобы бороться с os
, os.path
, glob
, shutil
и т. Д.
Итак, у нас есть 3 пути (возможно, дублируется):
mod_path
: это путь к простейшему вспомогательному скрипту src_path
: содержит пару файлов шаблонов , ожидающих копирования. cwd
: текущий каталог , назначение этого шаблона файлов. , и проблема в том, что у нас нет полного пути к src_path
, только знаете, что это относительный путь к mod_path
.
Теперь давайте решим это с удивительным pathlib
:
# Hope you don't be imprisoned by legacy Python code :)
from pathlib import Path
# `cwd`: current directory is straightforward
cwd = Path.cwd()
# `mod_path`: According to the accepted answer and combine with future power
# if we are in the `helper_script.py`
mod_path = Path(__file__).parent
# OR if we are `import helper_script`
mod_path = Path(helper_script.__file__).parent
# `src_path`: with the future power, it's just so straightforward
relative_path_1 = 'same/parent/with/helper/script/'
relative_path_2 = '../../or/any/level/up/'
src_path_1 = (mod_path / relative_path_1).resolve()
src_path_2 = (mod_path / relative_path_2).resolve()
В будущем это просто так просто. : D
Кроме того, мы можем выбирать и проверять и копировать / перемещать эти файлы шаблонов с помощью pathlib
:
if src_path != cwd:
# When we have different types of files in the `src_path`
for template_path in src_path.glob('*.ini'):
fname = template_path.name
target = cwd / fname
if not target.exists():
# This is the COPY action
with target.open(mode='wb') as fd:
fd.write(template_path.read_bytes())
# If we want MOVE action, we could use:
# template_path.replace(target)
filename = os.path.join(dir, 'relative', 'path', 'to', 'file', 'you' , 'want')
– ford 6 February 2014 в 19:51os.path.dirname(__file__)
может дать пустую строку, вместо этого используйтеos.path.dirname(os.path.abspath(__file__))
– Dmitry Trofimov 10 March 2015 в 23:03inspect.stack()
- это дорогая i> функция для вызова. Он извлекает информацию для всех кадров стека, которые вы затем отбрасываете и получаете только верхнюю. Он в основном называетinspect.getfile()
объектом модуля, который просто возвращаетmodule.__file__
. Вы гораздо лучше используете__file__
. – Martijn Pieters♦ 12 May 2018 в 19:05