Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

os.path AttributeError: 'str' object has no attribute 'exists'

Tags:

python

I'm trying to reproduce the code from this site: https://www.guru99.com/python-copy-file.html

The general idea is to copy a file using python. Although I can work my way around the errors, I also want to understand what I'm doing wrong in this case.

import shutil
from os import path
def main(filename):
    if path.exists(filename):
        src = path.realpath(filename)
        head, tail = path.split(src)
        dst = src + ".bak"
        shutil.copy(src,dst)

main('C:\\Users\\test.txt') #This raises the error
main('test.txt') #This works, if the file is in the same folder as the py script

If used with the full directory (main('C:\Users\test.txt')) The code returns the error AttributeError: 'str' object has no attribute 'exists'. If I remove the line with path.exists() I get a similar error: AttributeError: 'str' object has no attribute 'realpath'. By using the filename main('test.txt') everything works, as long as the file is in the same folder as the python script that contains the function.

So I tried reading the docs, which states for both path.exists() and path.realpath():

Changed in version 3.6: Accepts a path-like object.

Since I'm running 3.7.1 I went foward to check what is a "path-like object":

An object representing a file system path. A path-like object is either a str or bytes object representing a path, or an object implementing the os.PathLike protocol. An object that supports the os.PathLike protocol can be converted to a str or bytes file system path by calling the os.fspath() function; os.fsdecode() and os.fsencode() can be used to guarantee a str or bytes result instead, respectively. Introduced by PEP 519.

From that, given that I provided a string, I take it should be working. So what I'm missing?

like image 257
Justcurious Avatar asked Mar 08 '19 02:03

Justcurious


People also ask

Why does STR have no attribute ‘get’?

The AttributeError: ‘str’ object has no attribute ‘get’ occurs when you try to call the get () method on the string data type. The error also occurs if the calling method returns an string instead of a dictionary object. We can resolve the error by calling the get () method on the dictionary object instead of an string.

What is a path-like object?

An object representing a file system path. A path-like object is either a str or bytes object representing a path, or an object implementing the os.PathLike protocol.

How do I solve the error when accessing an attribute?

To solve the error, make sure the value is of the expected type before accessing the attribute. Here is an example of how the error occurs. We tried to access an attribute that doesn't exist on string objects and got the error.

How do I debug a variable with no attribute?

Using the hasattr function would handle the error if the attribute doesn't exist on the object, however you still have to figure out where the variable gets assigned a string in your code. A good way to start debugging is to print (dir (your_object)) and see what attributes a string has.


2 Answers

Your code:

import shutil
from os import path
def main(filename):
    if path.exists(filename):
        src = path.realpath(filename)
        head, tail = path.split(src)
        dst = src + ".bak"
        shutil.copy(src,dst)

main('C:\\Users\\test.txt') #This raises the error
main('test.txt') #This works, if the file is in the same folder as the py script

It works fine, but if you re-define a local variable named path, like this:

import shutil
from os import path


def main(filename):
    if path.exists(filename):
        src = path.realpath(filename)
        head, tail = path.split(src)
        dst = src + ".bak"
        shutil.copy(src, dst)

# The path variable here overrides the path in the main function.
path = 'abc'  

main('C:\\Users\\test.txt')  # This raises the error

This is just your code I guess, obviously this is a wrong example.

I would recommend using the os.path after import os, because the path variable name is very common, it is easy to conflict.

For a good example:

import shutil
import os


def main(filename):
    if os.path.exists(filename):
        src = os.path.realpath(filename)
        head, tail = os.path.split(src)
        dst = src + ".bak"
        shutil.copy(src, dst)

main('C:\\Users\\test.txt')
main('test.txt')
like image 56
DDGG Avatar answered Oct 17 '22 05:10

DDGG


Type on shell

Type(path)

And check result and value, maybe you redefine this import to a variable str.

like image 2
Leonardo Ramos Duarte Avatar answered Oct 17 '22 04:10

Leonardo Ramos Duarte