ฉันจะรับพา ธ และชื่อของไฟล์ที่กำลังทำงานอยู่ได้อย่างไร


482

ฉันมีสคริปต์ที่เรียกไฟล์สคริปต์อื่น ๆ แต่ฉันต้องได้รับ filepath ของไฟล์ที่กำลังทำงานอยู่ในกระบวนการ

ตัวอย่างเช่นสมมติว่าฉันมีสามไฟล์ ใช้execfile :

  • script_1.pyscript_2.pyโทร
  • ในทางกลับกันเรียกscript_2.pyscript_3.py

ฉันจะได้รับชื่อไฟล์และเส้นทางของscript_3.py, จากรหัสภายในscript_3.pyโดยไม่ต้องส่งผ่านข้อมูลที่เป็นข้อโต้แย้งจากscript_2.py?

(การดำเนินการos.getcwd()ส่งคืนไฟล์พา ธ ของสคริปต์เริ่มต้นต้นฉบับไม่ใช่ไฟล์ปัจจุบัน)



2
os.path.realpath ( ไฟล์ )
Girish Gupta

คำตอบ:


256

p1.py:

execfile("p2.py")

p2.py:

import inspect, os
print (inspect.getfile(inspect.currentframe()) # script filename (usually with path)
print (os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))) # script directory

11
ระวัง: การโทรนี้จะไม่ให้ผลลัพธ์เดียวกันกับสภาพแวดล้อมที่แตกต่างกัน ลองพิจารณายอมรับคำตอบของ Usagi ด้านล่าง: stackoverflow.com/a/6628348/851398
faraday

3
@faraday: คุณช่วยยกตัวอย่างได้ไหม ฉันตอบคำถามที่คล้ายกันโดยใช้inspect.getabsfile()และใช้ได้กับทุกกรณีที่ฉันได้ลอง
jfs

1
@Sagi เป็นคำตอบที่ดีกว่านี้จริงหรือ
Dror

4
nah user13993 จับมันได้ดีกว่า
osirisgothra

6
user13993 ทำเล็บจริง ๆ ควรเป็นos.path.realpath(__file__)
uchuugaka

566
__file__

อย่างที่คนอื่นพูด คุณอาจต้องการใช้os.path.realpathเพื่อกำจัด symlink:

import os

os.path.realpath(__file__)

14
เราต้องระมัดระวังวิธีนี้เนื่องจากบางครั้ง__file__จะส่งคืน 'script_name.py' และเวลาอื่น ๆ 'script_name.pyc' ดังนั้นเอาต์พุตไม่เสถียร
mechatroner

27
แต่เนื่องจากเราใช้เส้นทางของไฟล์นี้เท่านั้นจึงไม่เกี่ยวข้อง
Uwe Koloska

5
นี่คือแปลก: เมื่อทำงานจากบรรทัดคำสั่ง "__file__"ในอัญประกาศ (เป็นสตริง) ให้ dir จากที่ cmd จะทำงาน แต่__file__ (โดยไม่มีเครื่องหมายอัญประกาศให้เส้นทางไปยังไฟล์ต้นฉบับ ... ทำไมเป็นเช่นนั้น
muon

7
@muon ไม่มีการตรวจสอบว่าสตริงชื่อไฟล์มีการส่งผ่านหรือไม่และเนื่องจากพา ธ ของไฟล์สัมพันธ์กับ cwd นั่นคือสิ่งที่os.path.realpathฟังก์ชั่นสันนิษฐานว่าเป็นdirส่วนหนึ่งของพา ธ os.path.dirname(os.path.realpath(__file__))ส่งคืนไดเร็กทอรีด้วยไฟล์ os.path.dirname(os.path.realpath("__file__"))ส่งกลับ cwd os.path.dirname(os.path.realpath("here_be_dragons"))ส่งคืน cwd ด้วยเช่นกัน
Jamie Bull

86

อัปเดต 2018-11-28:

นี่คือบทสรุปของการทดสอบกับ Python 2 และ 3 ด้วย

main.py - วิ่ง foo.py
foo.py - วิ่ง lib / bar.py
lib / bar.py - พิมพ์นิพจน์พา ธ ไฟล์

| Python | Run statement       | Filepath expression                    |
|--------+---------------------+----------------------------------------|
|      2 | execfile            | os.path.abspath(inspect.stack()[0][1]) |
|      2 | from lib import bar | __file__                               |
|      3 | exec                | (wasn't able to obtain it)             |
|      3 | import lib.bar      | __file__                               |

สำหรับ Python 2 อาจจะชัดเจนกว่าที่จะเปลี่ยนเป็นแพ็กเกจเพื่อให้สามารถใช้งานได้from lib import bar- เพียงเพิ่ม__init__.pyไฟล์เปล่าลงในสองโฟลเดอร์

สำหรับ Python 3 execfileไม่มีอยู่ - ทางเลือกที่ใกล้ที่สุดคือexec(open(<filename>).read())แม้ว่าจะมีผลกับกรอบสแต็ก มันง่ายที่สุดในการใช้import fooและimport lib.bar- ไม่__init__.pyจำเป็นต้องใช้ไฟล์

ดูเพิ่มเติมความแตกต่างระหว่างการนำเข้าและ execfile


คำตอบเดิม:

นี่คือการทดลองตามคำตอบในหัวข้อนี้ - ด้วย Python 2.7.10 บน Windows

กองซ้อนที่ใช้เป็นเพียงกลุ่มเดียวที่ดูเหมือนจะให้ผลลัพธ์ที่เชื่อถือได้ สองคนสุดท้ายมีไวยากรณ์ที่สั้นที่สุดคือ -

print os.path.abspath(inspect.stack()[0][1])                   # C:\filepaths\lib\bar.py
print os.path.dirname(os.path.abspath(inspect.stack()[0][1]))  # C:\filepaths\lib

นี่คือการเพิ่มเหล่านี้ไปยังsysเป็นฟังก์ชั่น! เครดิตให้กับ @Usagi และ @pablog

อ้างอิงจากไฟล์สามไฟล์ต่อไปนี้และเรียกใช้ main.py จากโฟลเดอร์ด้วยpython main.py(ลองใช้ไฟล์ exec กับเส้นทางแบบสัมบูรณ์และการโทรจากโฟลเดอร์อื่น)

C: \ filepaths \ main.py: execfile('foo.py')
C: \ filepaths \ foo.py: execfile('lib/bar.py')
C: \ filepaths \ lib \ bar.py:

import sys
import os
import inspect

print "Python " + sys.version
print

print __file__                                        # main.py
print sys.argv[0]                                     # main.py
print inspect.stack()[0][1]                           # lib/bar.py
print sys.path[0]                                     # C:\filepaths
print

print os.path.realpath(__file__)                      # C:\filepaths\main.py
print os.path.abspath(__file__)                       # C:\filepaths\main.py
print os.path.basename(__file__)                      # main.py
print os.path.basename(os.path.realpath(sys.argv[0])) # main.py
print

print sys.path[0]                                     # C:\filepaths
print os.path.abspath(os.path.split(sys.argv[0])[0])  # C:\filepaths
print os.path.dirname(os.path.abspath(__file__))      # C:\filepaths
print os.path.dirname(os.path.realpath(sys.argv[0]))  # C:\filepaths
print os.path.dirname(__file__)                       # (empty string)
print

print inspect.getfile(inspect.currentframe())         # lib/bar.py

print os.path.abspath(inspect.getfile(inspect.currentframe())) # C:\filepaths\lib\bar.py
print os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) # C:\filepaths\lib
print

print os.path.abspath(inspect.stack()[0][1])          # C:\filepaths\lib\bar.py
print os.path.dirname(os.path.abspath(inspect.stack()[0][1]))  # C:\filepaths\lib
print

72

ฉันคิดว่านี่สะอาดกว่า:

import inspect
print inspect.stack()[0][1]

และรับข้อมูลเช่นเดียวกับ:

print inspect.getfile(inspect.currentframe())

โดยที่ [0] เป็นเฟรมปัจจุบันในสแต็ก (ด้านบนของสแต็ค) และ [1] สำหรับชื่อไฟล์ให้เพิ่มไปข้างหลังในสแต็กเช่น

print inspect.stack()[1][1]

จะเป็นชื่อไฟล์ของสคริปต์ที่เรียกว่าเฟรมปัจจุบัน นอกจากนี้การใช้ [-1] จะนำคุณไปสู่ด้านล่างของสแต็กซึ่งเป็นสคริปต์การโทรดั้งเดิม


4
ไม่แนะนำให้พึ่งพาตำแหน่งภายใน tuple ยังไม่ชัดเจนว่าข้อมูลใดที่คุณพยายามรับเมื่ออ่านรหัส
jpmc26

5
inspect.getfile()ส่งกลับ__file__แอตทริบิวต์ถ้าผ่านวัตถุโมดูล inspect.currentframe()ส่งคืนโมดูล Ergo __file__นี้เป็นวิธีที่แพงพูดว่า
Martijn Pieters

inspect.stack()เป็นฟังก์ชั่นที่มีราคาแพงมากเกินกว่าจะเป็นinspect.currentframe()จริงและมันก็เรียกใช้inspect.getfile()บนออบเจ็กต์โมดูล
Martijn Pieters

42
import os
os.path.dirname(__file__) # relative directory path
os.path.abspath(__file__) # absolute file path
os.path.basename(__file__) # the file name only

1
ฉันเพิ่งลองความคิดเห็นของ @Pat Notz ฉันคิดว่าคุณสามารถรับชื่อไฟล์__file__ได้
hlin117

ใน Python3 os.path.dirnameจะให้เส้นทางสัมพัทธ์กับคุณที่คุณใช้งานสคริปต์ เช่นในจะเป็นและไม่ได้เป็นเส้นทางที่แน่นอนสคริปต์ ฉันกำลังมองหา abspath แต่ลบชื่อของสคริปต์ องค์ประกอบแรกของ sys.path เห็นได้ชัดคือคำตอบ python ../../test.pyos.path.dirname../../sys.path[0]
aerijman

37

คำแนะนำที่ทำเครื่องหมายว่าดีที่สุดนั้นเป็นจริงทั้งหมดหากสคริปต์ของคุณประกอบด้วยไฟล์เดียวเท่านั้น

หากคุณต้องการค้นหาชื่อของไฟล์เรียกทำงาน (เช่นไฟล์รูทที่ส่งไปยังตัวแปลของไพ ธ อนสำหรับโปรแกรมปัจจุบัน) จากไฟล์ที่อาจนำเข้าเป็นโมดูลคุณต้องทำสิ่งนี้ (สมมติว่านี่เป็นไฟล์ ชื่อfoo.py ):

import inspect

print inspect.stack()[-1][1]

เพราะสิ่งสุดท้าย ( [-1]) บนสแต็กเป็นสิ่งแรกที่เข้าไป (สแต็คคือโครงสร้างข้อมูล LIFO / FILO)

จากนั้นในไฟล์bar.pyหากคุณimport fooจะพิมพ์bar.pyแทนที่จะเป็นfoo.pyซึ่งจะเป็นมูลค่าของสิ่งเหล่านี้ทั้งหมด:

  • __file__
  • inspect.getfile(inspect.currentframe())
  • inspect.stack()[0][1]

มันใช้งานได้ดี แต่ไม่ใช่สำหรับการทดสอบหน่วยบน eclipse ฉันได้รับ
/home/user/Softwares/eclipse/plugins/org.python.pydev_4.5.5.201603221110/pysrc

2
นี่เป็นวิธีสะกดคำที่มีราคาแพงsys.modules['__main__'].__file__จริงๆ
Martijn Pieters

14
import os
print os.path.basename(__file__)

สิ่งนี้จะให้ชื่อไฟล์เราเท่านั้น เช่นถ้าไฟล์ abspath คือ c: \ abcd \ abc.py แล้วบรรทัดที่ 2 จะพิมพ์ abc.py


14

ยังไม่ชัดเจนว่าคุณหมายถึงอะไร "filepath ของไฟล์ที่กำลังทำงานภายในกระบวนการ" sys.argv[0]มักจะมีที่ตั้งของสคริปต์ที่ถูกเรียกโดย Python interpreter ตรวจสอบเอกสาร sysสำหรับรายละเอียดเพิ่มเติม

ในฐานะที่เป็น @Tim และ @Pat Notz ได้ชี้ให้เห็นแอตทริบิวต์ __file__ ให้การเข้าถึง

ไฟล์ที่โมดูลถูกโหลดถ้ามันถูกโหลดจากไฟล์


1
"print os.path.abspath ( ไฟล์ )" และ "print inspect.getfile (inspect.currentframe ())" ไม่ทำงานเมื่อเราส่งโปรแกรมไพ ธ อนไปยัง win32 exe sys.argv เท่านั้น [0] ใช้งานได้! :) แต่คุณจะได้ชื่อเท่านั้น!
aF

11

ฉันมีสคริปต์ที่ต้องทำงานภายใต้สภาพแวดล้อมของ windows รหัสนี้เป็นสิ่งที่ฉันได้ทำไปแล้ว:

import os,sys
PROJECT_PATH = os.path.abspath(os.path.split(sys.argv[0])[0])

เป็นการตัดสินใจที่แฮ็ค แต่มันไม่ต้องใช้ห้องสมุดภายนอกและเป็นสิ่งที่สำคัญที่สุดในกรณีของฉัน


1
ฉันต้อง "import os, sys" สำหรับสิ่งนี้ แต่จนถึงตอนนี้มันเป็นคำตอบที่ดีที่สุดที่จริง ๆ แล้วคืนค่าเส้นทางโดยไม่มีชื่อไฟล์ที่ท้ายของสตริง
emmagras


8
import os
os.path.dirname(os.path.abspath(__file__))

ไม่จำเป็นต้องตรวจสอบหรือห้องสมุดอื่น ๆ

สิ่งนี้ใช้ได้สำหรับฉันเมื่อฉันต้องนำเข้าสคริปต์ (จากไดเรกทอรีที่แตกต่างจากนั้นก็เรียกใช้สคริปต์) ซึ่งใช้ไฟล์การกำหนดค่าที่อยู่ในโฟลเดอร์เดียวกับสคริปต์ที่นำเข้า


สิ่งนี้จะไม่สร้างคำตอบที่ต้องการหากไดเรกทอรีการทำงานปัจจุบัน (os.getcwd) แตกต่างจากไดเรกทอรีที่มีไฟล์อยู่
หมอนเหล็ก

2
งั้นเหรอ ทำงานได้ดีสำหรับฉันในกรณีนี้ ฉันได้รับไดเรกทอรีไฟล์จะอยู่ใน.
ไมเคิล Mior

@IronPillow บางทีคำตอบนี้จะช่วยคุณในสิ่งที่คุณต้องการ stackoverflow.com/a/41546830/3123191
Kwuite


6
import sys

print sys.path[0]

สิ่งนี้จะพิมพ์พา ธ ของสคริปต์ที่กำลังเรียกใช้งานในปัจจุบัน


2
sys.path [0] เป็นประโยชน์อย่างมาก แต่ให้เส้นทางของ script1 ไม่ Script3 ตามที่ร้องขอ
เจมส์

อย่างน้อยใน OS X ด้วย 2.7 ฉันไม่คิดว่ามันน่าเชื่อถือ มันทำงานได้ถ้ารันไฟล์เดียวกันโดยตรง ไม่ได้ผลจากการ
ลอกเลียนแบบ

5

ฉันคิดว่ามันเป็นเพียง__file__ เสียงเช่นคุณอาจต้องการที่จะชำระเงินโมดูลตรวจสอบ


อ่าาา ... execfile มันยุ่งยาก ดูโพสต์อื่น ๆ ของฉันเกี่ยวกับการใช้โมดูลตรวจสอบ
Pat Notz

4

คุณสามารถใช้ได้ inspect.stack()

import inspect,os
inspect.stack()[0]  => (<frame object at 0x00AC2AC0>, 'g:\\Python\\Test\\_GetCurrentProgram.py', 15, '<module>', ['print inspect.stack()[0]\n'], 0)
os.path.abspath (inspect.stack()[0][1]) => 'g:\\Python\\Test\\_GetCurrentProgram.py'

4

เนื่องจาก Python 3 เป็นกระแสหลักฉันจึงต้องการpathlibคำตอบเพราะฉันเชื่อว่าตอนนี้อาจเป็นเครื่องมือที่ดีกว่าสำหรับการเข้าถึงไฟล์และพา ธ ข้อมูล

from pathlib import Path

current_file: Path = Path(__file__).resolve()

หากคุณกำลังมองหาไดเรกทอรีของแฟ้มปัจจุบันมันเป็นเรื่องง่ายเหมือนการเพิ่ม.parentไปที่Path()คำสั่ง:

current_path: Path = Path(__file__).parent.resolve()

3
import sys
print sys.argv[0]

10
น่าเสียดายที่วิธีนี้ใช้ได้ผลก็ต่อเมื่อสคริปต์ถูกเรียกด้วยพา ธ เต็มเพราะจะส่งกลับเฉพาะ "อาร์กิวเมนต์แรก" ในบรรทัดคำสั่งซึ่งเป็นการเรียกใช้สคริปต์
cregox

2

สิ่งนี้น่าจะใช้ได้:

import os,sys
filename=os.path.basename(os.path.realpath(sys.argv[0]))
dirname=os.path.dirname(os.path.realpath(sys.argv[0]))

2
print(__file__)
print(__import__("pathlib").Path(__file__).parent)

4
คำตอบรหัสเท่านั้นที่จะหมดกำลังใจ โปรดเพิ่มคำอธิบายเกี่ยวกับวิธีการแก้ไขปัญหาหรือวิธีการนี้แตกต่างจากคำตอบที่มีอยู่ จากการทบทวน
Nick

1

เพื่อรับไดเร็กทอรีของสคริปต์การเรียกใช้งาน

 print os.path.dirname( inspect.getfile(inspect.currentframe()))

1

ฉันมักจะใช้คุณสมบัติระบบปฏิบัติการของไดเรกทอรีการทำงานปัจจุบันหรือ CWD เสมอ นี่เป็นส่วนหนึ่งของไลบรารีมาตรฐานและง่ายต่อการนำไปใช้ นี่คือตัวอย่าง:

    import os
    base_directory = os.getcwd()

1
คุณสามารถแก้ไขคำตอบเพื่อนำไปใช้กับคำถามที่โพสต์ได้หรือไม่ คำตอบนี้ใช้ไม่ได้กับคำถาม "ฉันจะหาพา ธ และชื่อของไฟล์ที่กำลังใช้งานอยู่ได้อย่างไร "
Marco

1
นี่ให้พา ธ จากตำแหน่งที่คุณรันคำสั่ง python ดังนั้นดูเหมือนว่าจะทำงานเมื่อคุณเรียกใช้python script.pyคำสั่งในโฟลเดอร์เดียวกันที่คุณมีอยู่แล้วในความเป็นจริงมันเหมือนกับการทำงานpwdบน linux
จอร์จ

0

ฉันใช้วิธีการกับ __file__
os.path.abspath(__file__)
แต่มีเคล็ดลับเล็กน้อยมันจะส่งคืนไฟล์. py เมื่อมีการเรียกใช้รหัสในครั้งแรกการเรียกใช้ครั้งต่อไปจะให้ชื่อไฟล์ * .pyc
ดังนั้นฉันจึงอยู่กับ:
inspect.getfile(inspect.currentframe())
หรือ
sys._getframe().f_code.co_filename


0

ผมเขียนฟังก์ชั่นที่ใช้เวลาในการคราสบัญชีดีบักและUnitTest จะส่งคืนโฟลเดอร์ของสคริปต์แรกที่คุณเปิดใช้ คุณสามารถเลือกระบุ__FILE__ var แต่สิ่งที่สำคัญคือการที่คุณไม่จำเป็นต้องแบ่งปันตัวแปรนี้ทั่วทุกลำดับชั้นโทร

บางทีคุณสามารถจัดการกับคนอื่นได้ในบางกรณีที่ฉันไม่เห็น แต่สำหรับฉันมันก็โอเค

import inspect, os
def getRootDirectory(_file_=None):
    """
    Get the directory of the root execution file
    Can help: http://stackoverflow.com/questions/50499/how-do-i-get-the-path-and-name-of-the-file-that-is-currently-executing
    For eclipse user with unittest or debugger, the function search for the correct folder in the stack
    You can pass __file__ (with 4 underscores) if you want the caller directory
    """
    # If we don't have the __file__ :
    if _file_ is None:
        # We get the last :
        rootFile = inspect.stack()[-1][1]
        folder = os.path.abspath(rootFile)
        # If we use unittest :
        if ("/pysrc" in folder) & ("org.python.pydev" in folder):
            previous = None
            # We search from left to right the case.py :
            for el in inspect.stack():
                currentFile = os.path.abspath(el[1])
                if ("unittest/case.py" in currentFile) | ("org.python.pydev" in currentFile):
                    break
                previous = currentFile
            folder = previous
        # We return the folder :
        return os.path.dirname(folder)
    else:
        # We return the folder according to specified __file__ :
        return os.path.dirname(os.path.realpath(_file_))

0

หากต้องการให้ความสอดคล้องในการย้ายข้อมูลข้ามแพลตฟอร์ม (macOS / Windows / Linux) ให้ลอง:

path = r'%s' % os.getcwd().replace('\\','/')


2
นี่เป็นสิ่งที่ผิด สิ่งนี้ทำให้คุณได้รับเส้นทางปัจจุบัน แต่ไม่ใช่เส้นทางของไฟล์ปัจจุบัน
Charles Plager

0

วิธีที่ง่ายที่สุดคือ:

ในscript_1.py:

import subprocess
subprocess.call(['python3',<path_to_script_2.py>])

ในscript_2.py:

sys.argv[0]

PS: ฉันได้พยายามexecfileแต่เนื่องจากมันอ่าน script_2.py เป็นสตริงกลับsys.argv[0]<string>


0

นี่คือสิ่งที่ฉันใช้เพื่อให้ฉันสามารถโยนรหัสได้ทุกที่โดยไม่มีปัญหา __name__ถูกกำหนดไว้เสมอ แต่__file__จะมีการกำหนดไว้เมื่อรหัสถูกเรียกใช้เป็นไฟล์ (เช่นไม่ใช่ใน IDLE / iPython)

    if '__file__' in globals():
        self_name = globals()['__file__']
    elif '__file__' in locals():
        self_name = locals()['__file__']
    else:
        self_name = __name__

อีกทางเลือกหนึ่งนี้สามารถเขียนเป็น:

self_name = globals().get('__file__', locals().get('__file__', __name__))

-2

คำตอบส่วนใหญ่เขียนไว้ใน Python เวอร์ชัน 2.x หรือเก่ากว่า ใน Python 3.x ไวยากรณ์ของฟังก์ชั่นการพิมพ์เปลี่ยนไปเพื่อให้ต้องใส่วงเล็บเช่น print ()

ดังนั้นคำตอบคะแนนสูงก่อนหน้านี้จาก user13993 ใน Python 2.x:

import inspect, os
print inspect.getfile(inspect.currentframe()) # script filename (usually with path)
print os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) # script directory

กลายเป็น Python 3.x:

import inspect, os
print(inspect.getfile(inspect.currentframe())) # script filename (usually with path)
print(os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) ) # script directory

-3

หากคุณต้องการเพียงชื่อไฟล์โดยไม่มี./หรือ.pyคุณสามารถลองนี้

filename = testscript.py
file_name = __file__[2:-3]

file_name จะพิมพ์ testcript คุณสามารถสร้างสิ่งที่คุณต้องการโดยการเปลี่ยนดัชนีภายใน []


-3
import os

import wx


# return the full path of this file
print(os.getcwd())

icon = wx.Icon(os.getcwd() + '/img/image.png', wx.BITMAP_TYPE_PNG, 16, 16)

# put the icon on the frame
self.SetIcon(icon)

7
os.getcwd () ส่งคืนไดเรกทอรีการทำงานปัจจุบันของกระบวนการไม่ใช่ไดเรกทอรีของไฟล์ที่กำลังทำงาน สิ่งนี้อาจปรากฏขึ้นเพื่อส่งคืนผลลัพธ์ที่ถูกต้อง แต่มีหลายกรณีที่ผลลัพธ์จะไม่ใช่ไดเรกทอรีหลักของไฟล์ปัจจุบัน ดีกว่าการใช้ os.path.dirname ( ไฟล์ ) ตามที่แนะนำข้างต้น
samaspin
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.