mirror of
https://github.com/satwikkansal/wtfpython
synced 2025-05-19 18:53:46 +02:00
update farsi translation - section 1
This commit is contained in:
parent
ddab1b6ad2
commit
2ca7ebe2a4
217
translations/fa-farsi/section1-temp.md
vendored
217
translations/fa-farsi/section1-temp.md
vendored
@ -585,6 +585,7 @@ TypeError: unhashable type: 'dict'
|
||||
>>> len(another_set)
|
||||
2
|
||||
```
|
||||
|
||||
پس بیثباتی تو این رفتار به خاطر اینه که مقدار `another_ordered_dict in another_set` برابر با `False` هست چون `ordered_dict` از قبل داخل `another_set` هست و همونطور که قبلا مشاهده کردید، مقدار `ordered_dict == another_ordered_dict` برابر با `False` هست.
|
||||
|
||||
---
|
||||
@ -788,3 +789,219 @@ False
|
||||
- در مثال بالا، عبارت `(not None)` برابره با مقدار `True` از اونجایی که مقدار `None` در زمینه boolean به `False` تبدیل میشه. پس کل عبارت معادل عبارت `'something' is True` میشه.
|
||||
|
||||
---
|
||||
|
||||
|
||||
### ▶ یک بازی دوز که توش X همون اول برنده میشه!
|
||||
<!-- Example ID: 69329249-bdcb-424f-bd09-cca2e6705a7a --->
|
||||
|
||||
```py
|
||||
# بیاید یک سطر تشکیل بدیم
|
||||
row = [""] * 3 #row i['', '', '']
|
||||
# حالا بیاید تخته بازی رو ایجاد کنیم
|
||||
board = [row] * 3
|
||||
```
|
||||
|
||||
**خروجی:**
|
||||
|
||||
```py
|
||||
>>> board
|
||||
[['', '', ''], ['', '', ''], ['', '', '']]
|
||||
>>> board[0]
|
||||
['', '', '']
|
||||
>>> board[0][0]
|
||||
''
|
||||
>>> board[0][0] = "X"
|
||||
>>> board
|
||||
[['X', '', ''], ['X', '', ''], ['X', '', '']]
|
||||
```
|
||||
|
||||
ما که سهتا `"X"` نذاشتیم. گذاشتیم مگه؟
|
||||
|
||||
#### 💡 توضیحات:
|
||||
|
||||
وقتی متغیر `row` رو تشکیل میدیم، تصویر زیر نشون میده که چه اتفاقی در حافظه دستگاه میافته.
|
||||
|
||||
<p align="center">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="/images/tic-tac-toe/after_row_initialized_dark_theme.svg">
|
||||
<source media="(prefers-color-scheme: light)" srcset="/images/tic-tac-toe/after_row_initialized.svg">
|
||||
<img alt="Shows a memory segment after row is initialized." src="/images/tic-tac-toe/after_row_initialized.svg">
|
||||
</picture>
|
||||
</p>
|
||||
|
||||
و وقتی متغیر `board` رو با ضرب کردن متغیر `row` تشکیل میدیم، تصویر زیر به صورت کلی نشون میده که چه اتفاقی در حافظه میافته (هر کدوم از عناصر `board[0]`، `board[1]` و `board[2]` در حافظه به لیست یکسانی به نشانی `row` اشاره میکنند).
|
||||
|
||||
<p align="center">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="/images/tic-tac-toe/after_board_initialized_dark_theme.svg">
|
||||
<source media="(prefers-color-scheme: light)" srcset="/images/tic-tac-toe/after_board_initialized.svg">
|
||||
<img alt="Shows a memory segment after board is initialized." src="/images/tic-tac-toe/after_board_initialized.svg">
|
||||
</picture>
|
||||
</p>
|
||||
|
||||
ما میتونیم با استفاده نکردن از متغیر `row` برای تولید متغیر `board` از این سناریو پرهیز کنیم. (در [این](https://github.com/satwikkansal/wtfpython/issues/68) موضوع پرسیده شده).
|
||||
|
||||
```py
|
||||
>>> board = [['']*3 for _ in range(3)]
|
||||
>>> board[0][0] = "X"
|
||||
>>> board
|
||||
[['X', '', ''], ['', '', ''], ['', '', '']]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
|
||||
### ▶ متغیر شرودینگر *
|
||||
<!-- Example ID: 4dc42f77-94cb-4eb5-a120-8203d3ed7604 --->
|
||||
|
||||
|
||||
```py
|
||||
funcs = []
|
||||
results = []
|
||||
for x in range(7):
|
||||
def some_func():
|
||||
return x
|
||||
funcs.append(some_func)
|
||||
results.append(some_func()) # note the function call here
|
||||
|
||||
funcs_results = [func() for func in funcs]
|
||||
```
|
||||
|
||||
**خروجی:**
|
||||
```py
|
||||
>>> results
|
||||
[0, 1, 2, 3, 4, 5, 6]
|
||||
>>> funcs_results
|
||||
[6, 6, 6, 6, 6, 6, 6]
|
||||
```
|
||||
|
||||
مقدار `x` در هر تکرار حلقه قبل از اضافه کردن `some_func` به لیست `funcs` متفاوت بود، ولی همه توابع در خارج از حلقه مقدار `6` رو برمیگردونند.
|
||||
|
||||
2.
|
||||
|
||||
```py
|
||||
>>> powers_of_x = [lambda x: x**i for i in range(10)]
|
||||
>>> [f(2) for f in powers_of_x]
|
||||
[512, 512, 512, 512, 512, 512, 512, 512, 512, 512]
|
||||
```
|
||||
|
||||
#### 💡 توضیحات:
|
||||
* وقتی یک تابع رو در داخل یک حلقه تعریف میکنیم که در بدنهاش از متغیر اون حلقه استفاده شده، بست این تابع به *متغیر* وصله، نه *مقدار* اون. تابع به جای اینکه از مقدار `x` در زمان تعریف تابع استفاده کنه، در زمینه اطرافش دنبال `x` میگرده. پس همه این توابع از آخرین مقداری که به متغیر `x` مقداردهی شده برای محاسباتشون استفاده میکنند. ما میتونیم ببینیم که این توابع از متغیر `x` که در زمینه اطرافشون (*نه* از متغیر محلی) هست، استفاده میکنند، به این صورت:
|
||||
|
||||
```py
|
||||
>>> import inspect
|
||||
>>> inspect.getclosurevars(funcs[0])
|
||||
ClosureVars(nonlocals={}, globals={'x': 6}, builtins={}, unbound=set())
|
||||
```
|
||||
|
||||
از اونجایی که `x` یک متغیر سراسریه (گلوبال)، ما میتونیم مقداری که توابع داخل `funcs` دنبالشون میگردند و برمیگردونند رو با بهروز کردن `x` تغییر بدیم:
|
||||
|
||||
```py
|
||||
>>> x = 42
|
||||
>>> [func() for func in funcs]
|
||||
[42, 42, 42, 42, 42, 42, 42]
|
||||
```
|
||||
|
||||
* برای رسیدن به رفتار موردنظر شما میتونید متغیر حلقه رو به عنوان یک متغیر اسمدار به تابع بدید. **چرا در این صورت کار میکنه؟** چون اینجوری یک متغیر در دامنه خود تابع تعریف میشه. تابع دیگه دنبال مقدار `x` در دامنه اطراف (سراسری) نمیگرده ولی یک متغیر محلی برای ذخیره کردن مقدار `x` در اون لحظه میسازه.
|
||||
|
||||
```py
|
||||
funcs = []
|
||||
for x in range(7):
|
||||
def some_func(x=x):
|
||||
return x
|
||||
funcs.append(some_func)
|
||||
```
|
||||
|
||||
**خروجی:**
|
||||
|
||||
```py
|
||||
>>> funcs_results = [func() for func in funcs]
|
||||
>>> funcs_results
|
||||
[0, 1, 2, 3, 4, 5, 6]
|
||||
```
|
||||
|
||||
دیگه از متغیر `x` در دامنه سراسری استفاده نمیکنه:
|
||||
|
||||
```py
|
||||
>>> inspect.getclosurevars(funcs[0])
|
||||
ClosureVars(nonlocals={}, globals={}, builtins={}, unbound=set())
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
|
||||
### ▶ اول مرغ بوده یا تخم مرغ؟ *
|
||||
<!-- Example ID: 60730dc2-0d79-4416-8568-2a63323b3ce8 --->
|
||||
1\.
|
||||
```py
|
||||
>>> isinstance(3, int)
|
||||
True
|
||||
>>> isinstance(type, object)
|
||||
True
|
||||
>>> isinstance(object, type)
|
||||
True
|
||||
```
|
||||
|
||||
پس کدوم کلاس پایه "نهایی" هست؟ راستی سردرگمی بیشتری هم تو راهه.
|
||||
|
||||
2\.
|
||||
|
||||
```py
|
||||
>>> class A: pass
|
||||
>>> isinstance(A, A)
|
||||
False
|
||||
>>> isinstance(type, type)
|
||||
True
|
||||
>>> isinstance(object, object)
|
||||
True
|
||||
```
|
||||
|
||||
3\.
|
||||
|
||||
```py
|
||||
>>> issubclass(int, object)
|
||||
True
|
||||
>>> issubclass(type, object)
|
||||
True
|
||||
>>> issubclass(object, type)
|
||||
False
|
||||
```
|
||||
|
||||
|
||||
#### 💡 توضیحات
|
||||
|
||||
- در پایتون، `type` یک [متاکلاس](https://realpython.com/python-metaclasses/) است.
|
||||
- در پایتون **همه چیز** یک `object` است، که کلاسها و همچنین نمونههاشون (یا همان instance های کلاسها) هم شامل این موضوع میشن.
|
||||
- کلاس `type` یک متاکلاسه برای کلاس `object` و همه کلاسها (همچنین کلاس `type`) به صورت مستقیم یا غیرمستقیم از کلاس `object` ارث بری کرده است.
|
||||
- هیچ کلاس پایه واقعی بین کلاسهای `object` و `type` وجود نداره. سردرگمی که در قطعهکدهای بالا به وجود اومده، به خاطر اینه که ما به این روابط (یعنی `issubclass` و `isinstance`) از دیدگاه کلاسهای پایتون فکر میکنیم. رابطه بین `object` و `type` رو در پایتون خالص نمیشه بازتولید کرد. برای اینکه دقیقتر باشیم، رابطههای زیر در پایتون خالص نمیتونند بازتولید بشن.
|
||||
+ کلاس A یک نمونه از کلاس B، و کلاس B یک نمونه از کلاس A باشه.
|
||||
+ کلاس A یک نمونه از خودش باشه.
|
||||
-
|
||||
- این روابط بین `object` و `type` (که هردو نمونه یکدیگه و همچنین خودشون باشند) به خاطر "تقلب" در مرحله پیادهسازی، وجود دارند.
|
||||
|
||||
---
|
||||
|
||||
|
||||
### ▶ روابط بین زیرمجموعه کلاسها
|
||||
<!-- Example ID: 9f6d8cf0-e1b5-42d0-84a0-4cfab25a0bc0 --->
|
||||
**خروجی:**
|
||||
```py
|
||||
>>> from collections.abc import Hashable
|
||||
>>> issubclass(list, object)
|
||||
True
|
||||
>>> issubclass(object, Hashable)
|
||||
True
|
||||
>>> issubclass(list, Hashable)
|
||||
False
|
||||
```
|
||||
|
||||
ما انتظار داشتیم که روابط بین زیرکلاسها، انتقالی باشند، درسته؟ (یعنی اگه `A` زیرکلاس `B` باشه و `B` هم زیرکلاس `C` باشه، کلس `A` __باید__ زیرکلاس `C` باشه)
|
||||
|
||||
#### 💡 توضیحات:
|
||||
|
||||
* روابط بین زیرکلاسها در پایتون لزوما انتقالی نیستند. همه مجازند که تابع `__subclasscheck__` دلخواه خودشون رو در یک متاکلاس تعریف کنند.
|
||||
* وقتی عبارت `issubclass(cls, Hashable)` اجرا میشه، برنامه دنبال یک تابع "غیر نادرست" (یا non-Falsy) در `cls` یا هرچیزی که ازش ارثبری میکنه، میگرده.
|
||||
* از اونجایی که `object` قابل هش شدنه، ولی `list` اینطور نیست، رابطه انتقالی شکسته میشه.
|
||||
* توضیحات با جزئیات بیشتر [اینجا](https://www.naftaliharris.com/blog/python-subclass-intransitivity/) پیدا میشه.
|
||||
|
||||
---
|
||||
|
Loading…
x
Reference in New Issue
Block a user