Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
Community Proposals
Community Proposals
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read See all your notifications »
Q&A

Welcome to Software Development on Codidact!

Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.

Post History

80%
+6 −0
Q&A How is this code "dividing" by a string?

As already said by another answer, you're not "dividing a string by another string". I'd just like to complement by providing more details about how this works. If you try to divide a string by ...

posted 7mo ago by hkotsubo‭  ·  edited 7mo ago by hkotsubo‭

Answer
#2: Post edited by user avatar hkotsubo‭ · 2024-06-06T16:16:59Z (7 months ago)
  • As already said by [another answer](/posts/291667/291668#answer-291668), you're not "_dividing a string by another string_". I'd just like to complement by providing more details about how this works.
  • ---
  • If you try to divide a string by another, such as `x = 'a' / 'b'`, you'll get an error. Therefore, in your code, `HOME_DIRECTORY` is certainly not a string. But how can you "divide" it by a string?
  • Well, that's because in Python operators can be overloaded. In fact, when you call `x / y`, you're actually calling `type(x).__truediv__(x, y)`. This behaviour is described in the [language's Data Model](https://docs.python.org/3/reference/datamodel.html#emulating-numeric-types), and in this same link you can also find all the special methods and the respective arithmetic operators (such as `__add__` for `+`, `__sub__` for `-`, and so on).
  • For the division operator (`/`), the special method is `__truediv__`, and that's why this code works:
  • ```python
  • x = 10
  • print(type(x).__truediv__(x, 2)) # 5.0
  • print(type(x).__truediv__(x, 2) == x / 2) # True
  • ```
  • And this doesn't work for strings because they don't define such method:
  • ```python
  • print(int.__truediv__) # <slot wrapper '__truediv__' of 'int' objects>
  • print(str.__truediv__) # AttributeError: type object 'str' has no attribute '__truediv__'
  • ```
  • That's how we know that `HOME_DIRECTORY` is not a string. And based on the code, it's *probably* an instance of [`pathlib.Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path). If you look at the source code, [you'll see that this class defines the `__truediv__` method](https://github.com/python/cpython/blob/3.13/Lib/pathlib/_local.py#L148).
  • Not only that, but the method accepts either `Path` instances or strings as the second operand, and it internally converts all to a single `Path` object. That's why you can "divide" a `Path` by a string:
  • ```python
  • from pathlib import Path
  • p = Path('folder')
  • print(p / 'file.json') # folder/file.json
  • print(type(p).__truediv__(p, 'file.json')) # folder/file.json
  • # both are the same (calling the division operator is the same as calling __truediv__ method)
  • print(type(p).__truediv__(p, 'file.json') == p / 'file.json') # True
  • ```
  • If you think of `/` in terms of arithmetic division, of course it won't make sense to "divide" something by a string. But I believe this was made because the slash (`/`) is used as a path separator in \*nix systems, and allowing to write code such as `folder/file` would sound more "natural" and "intuitive", as we're dealing with `Path` instances (AKA "objects that represent filesystem paths"). So I could write `folder/file` just as I'd do in a command line.
  • In this case, you should stretch your mental model and forget about "divison". The `/` is just an operator that internally calls a specific method. The fact that numbers define it as the division operator is just a detail (a very convenient one, though, as it's the "expected" behaviour). But it's not required that this operator always means "division" in every case/context. Operator overloading allows you to redefine operators to have any meaning you want - whether it makes sense or not (for `Path` objects, it does IMO).
  • Take, for instance, the `+` operator. For numbers, it performs addition, but for strings, it concatenates them (`'1' + '2'` results in `'12'`). That's because strings define the `__add__` method, whose behaviour is different to `int` and `float`. Does it make sense to "add strings"? Maybe it does for lots of people, because that's a feature that many languages have and we're so used to it that it just became normal, but in a strict sense, it wouldn't make sense to perform arithmetic operations with text. With operator overloading, on the other hand, we can extend and change the behaviour and meaning of any operator, to suit our needs (such as "_for strings, `+` means concatenation instead of addition, because I said so_").
  • ---
  • As a side note, you can do it with your own classes:
  • ```python
  • class TrueDivTest:
  • def __truediv__(self, other):
  • return f'divided by {type(other).__name__}'
  • x = TrueDivTest()
  • print(x / 1) # divided by int
  • print(x / 'abc') # divided by str
  • print(x / []) # divided by list
  • print(x / x) # divided by TrueDivTest
  • ```
  • Note how the second operand can be of any type. In a real case scenario, of course, I would perform a different operation depending on the type, or restrict to specific types (and give an error if the type is not accepted), and so on. You're free to do anything with any operator, and give them any meaning you want. You're not restricted by the arithmetic definitions.
  • As already said by [another answer](/posts/291667/291668#answer-291668), you're not "_dividing a string by another string_". I'd just like to complement by providing more details about how this works.
  • ---
  • If you try to divide a string by another, such as `x = 'a' / 'b'`, you'll get an error. Therefore, in your code, `HOME_DIRECTORY` is certainly not a string. But how can you "divide" it by a string?
  • Well, that's because in Python operators can be overloaded. In fact, when you do `x / y`, you're actually calling `type(x).__truediv__(x, y)`. This behaviour is described in the [language's Data Model](https://docs.python.org/3/reference/datamodel.html#emulating-numeric-types), and in this same link you can also find all the special methods and the respective arithmetic operators (such as `__add__` for `+`, `__sub__` for `-`, and so on).
  • For the division operator (`/`), the special method is `__truediv__`, and that's why this code works:
  • ```python
  • x = 10
  • print(type(x).__truediv__(x, 2)) # 5.0
  • print(type(x).__truediv__(x, 2) == x / 2) # True
  • ```
  • And this doesn't work for strings because they don't define such method:
  • ```python
  • print(int.__truediv__) # <slot wrapper '__truediv__' of 'int' objects>
  • print(str.__truediv__) # AttributeError: type object 'str' has no attribute '__truediv__'
  • x = 'a'
  • print(type(x).__truediv__(x, 'b')) # AttributeError: type object 'str' has no attribute '__truediv__'
  • ```
  • That's how we know that `HOME_DIRECTORY` is not a string. And based on the code, it's *probably* an instance of [`pathlib.Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path). If you look at the source code, [you'll see that this class defines the `__truediv__` method](https://github.com/python/cpython/blob/3.13/Lib/pathlib/_local.py#L148).
  • Not only that, but the method accepts either `Path` instances or strings as the second operand, and it internally converts all to a single `Path` object. That's why you can "divide" a `Path` by a string:
  • ```python
  • from pathlib import Path
  • p = Path('folder')
  • print(p / 'file.json') # folder/file.json
  • print(type(p).__truediv__(p, 'file.json')) # folder/file.json
  • # both are the same (calling the division operator is the same as calling __truediv__ method)
  • print(type(p).__truediv__(p, 'file.json') == p / 'file.json') # True
  • ```
  • If you think of `/` in terms of arithmetic division, of course it won't make sense to "divide" something by a string. But I believe this was made because the slash (`/`) is used as a path separator in \*nix systems, and allowing to write code such as `folder/file` would sound more "natural" and "intuitive", as we're dealing with `Path` instances (AKA "objects that represent filesystem paths"). So I could write `folder/file` just as I'd do in a command line.
  • In this case, you should stretch your mental model and forget about "divison". The `/` is just an operator that internally calls a specific method. The fact that numbers define it as the division operator is just a detail (a very convenient one, though, as it's the "expected" behaviour). But it's not required that this operator always means "division" in every case/context. Operator overloading allows you to redefine operations to have any meaning you want - whether it makes sense or not (for `Path` objects, it does, IMO).
  • Take, for instance, the `+` operator. For numbers, it performs addition, but for strings, it concatenates them (`'1' + '2'` results in `'12'`). That's because strings define the `__add__` method, whose behaviour is different to `int` and `float`. Does it make sense to "add strings"? Maybe it does for lots of people, because that's a feature that many languages have and we're so used to it that it just became "normal", but in a strict sense, it wouldn't make sense to perform arithmetic operations with text. With operator overloading, on the other hand, we can extend and change the behaviour and meaning of any operator, to suit our needs (such as "_For strings, `+` means concatenation instead of addition, because I said so_").
  • ---
  • As a side note, you can do it with your own classes:
  • ```python
  • class TrueDivTest:
  • def __truediv__(self, other):
  • return f'divided by {type(other).__name__}'
  • x = TrueDivTest()
  • print(x / 1) # divided by int
  • print(x / 'abc') # divided by str
  • print(x / []) # divided by list
  • print(x / x) # divided by TrueDivTest
  • ```
  • Note how the second operand can be of any type. In a real case scenario, of course, I could perform a different action depending on the type, and/or restrict to specific types (and give an error if the type is not accepted), and so on. You're free to do anything with any operator, and give them any meaning you want. You're not restricted by the arithmetic definitions.
#1: Initial revision by user avatar hkotsubo‭ · 2024-06-06T14:00:10Z (7 months ago)
As already said by [another answer](/posts/291667/291668#answer-291668), you're not "_dividing a string by another string_". I'd just like to complement by providing more details about how this works.

---

If you try to divide a string by another, such as `x = 'a' / 'b'`, you'll get an error. Therefore, in your code, `HOME_DIRECTORY` is certainly not a string. But how can you "divide" it by a string?

Well, that's because in Python operators can be overloaded. In fact, when you call `x / y`, you're actually calling `type(x).__truediv__(x, y)`. This behaviour is described in the [language's Data Model](https://docs.python.org/3/reference/datamodel.html#emulating-numeric-types), and in this same link you can also find all the special methods and the respective arithmetic operators (such as `__add__` for `+`, `__sub__` for `-`, and so on).

For the division operator (`/`), the special method is `__truediv__`, and that's why this code works:

```python
x = 10
print(type(x).__truediv__(x, 2)) # 5.0
print(type(x).__truediv__(x, 2) == x / 2) # True
```

And this doesn't work for strings because they don't define such method:

```python
print(int.__truediv__) # <slot wrapper '__truediv__' of 'int' objects>
print(str.__truediv__) # AttributeError: type object 'str' has no attribute '__truediv__'
```

That's how we know that `HOME_DIRECTORY` is not a string. And based on the code, it's *probably* an instance of [`pathlib.Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path). If you look at the source code, [you'll see that this class defines the `__truediv__` method](https://github.com/python/cpython/blob/3.13/Lib/pathlib/_local.py#L148).

Not only that, but the method accepts either `Path` instances or strings as the second operand, and it internally converts all to a single `Path` object. That's why you can "divide" a `Path` by a string:

```python
from pathlib import Path

p = Path('folder')
print(p / 'file.json') # folder/file.json
print(type(p).__truediv__(p, 'file.json')) # folder/file.json

# both are the same (calling the division operator is the same as calling __truediv__ method)
print(type(p).__truediv__(p, 'file.json') == p / 'file.json') # True
```

If you think of `/` in terms of arithmetic division, of course it won't make sense to "divide" something by a string. But I believe this was made because the slash (`/`) is used as a path separator in \*nix systems, and allowing to write code such as `folder/file` would sound more "natural" and "intuitive", as we're dealing with `Path` instances (AKA "objects that represent filesystem paths"). So I could write `folder/file` just as I'd do in a command line.

In this case, you should stretch your mental model and forget about "divison". The `/` is just an operator that internally calls a specific method. The fact that numbers define it as the division operator is just a detail (a very convenient one, though, as it's the "expected" behaviour). But it's not required that this operator always means "division" in every case/context. Operator overloading allows you to redefine operators to have any meaning you want - whether it makes sense or not (for `Path` objects, it does IMO).

Take, for instance, the `+` operator. For numbers, it performs addition, but for strings, it concatenates them (`'1' + '2'` results in `'12'`). That's because strings define the `__add__` method, whose behaviour is different to `int` and `float`. Does it make sense to "add strings"? Maybe it does for lots of people, because that's a feature that many languages have and we're so used to it that it just became normal, but in a strict sense, it wouldn't make sense to perform arithmetic operations with text. With operator overloading, on the other hand, we can extend and change the behaviour and meaning of any operator, to suit our needs (such as "_for strings, `+` means concatenation instead of addition, because I said so_").

---

As a side note, you can do it with your own classes:

```python
class TrueDivTest:
    def __truediv__(self, other):
        return f'divided by {type(other).__name__}'

x = TrueDivTest()
print(x / 1) # divided by int
print(x / 'abc') # divided by str
print(x / []) # divided by list
print(x / x) # divided by TrueDivTest
```

Note how the second operand can be of any type. In a real case scenario, of course, I would perform a different operation depending on the type, or restrict to specific types (and give an error if the type is not accepted), and so on. You're free to do anything with any operator, and give them any meaning you want. You're not restricted by the arithmetic definitions.