PhiloLearn | فیلولرن – Telegram
PhiloLearn | فیلولرن
1.48K subscribers
512 photos
70 videos
70 files
543 links
🔵 فیلو یعنی مشتاق و لرن یعنی یادگیری
📘 در نتیجه فیلولرن یعنی مشتاق یادگیری 📘

https://www.youtube.com/@PhiloLearn

donate:
https://www.coffeete.ir/PhiloLearn
Download Telegram
۸. تست بنویسم؟ چه تستی؟ چقدر؟

جواب کوتاه:
آره، حتماً تست بنویس.
روی تست‌های اینتگریشن تمرکز کن.
برای بخش‌های مهم، ۶۰ تا ۸۰٪ پوشش کافیه.



اولویت تست‌ها:

‏1. Integration tests
تست مسیرهای واقعی کاربر (signup → login → dashboard)
‏2. Unit tests
تست منطق پیچیده (محاسبات، قوانین تجاری و …)
‏3. Edge case tests
تست حالت‌های خطا، ورودی‌های خراب، محدودیت‌ها


چیا رو تست نکن؟

- عملکرد داخلی و آماده‌ی Django
- کتابخونه‌های شخص ثالث
‏- getter/setterهای ساده
- کدهای تولیدی (auto-generated)


مثال‌ها

تست اینتگریشن خوب

class UserSignupTest(TestCase):
def test_user_can_signup_and_login(self):
# Signup
response = self.client.post('/signup/', {
'username': 'testuser',
'email': 'test@example.com',
'password': 'testpass123'
})
self.assertEqual(response.status_code, 302)

# User created
self.assertEqual(User.objects.count(), 1)
user = User.objects.first()
self.assertEqual(user.username, 'testuser')

# Can login
login_success = self.client.login(
username='testuser',
password='testpass123'
)
self.assertTrue(login_success)



تست واحد (unit test) برای منطق پیچیده

class OrderCalculationTest(TestCase):
def test_order_total_with_discount_and_tax(self):
order = Order.objects.create(subtotal=100)
order.apply_discount(code='SAVE20') # 20% off
order.calculate_tax(rate=0.08) # 8% tax

self.assertEqual(order.discount, 20)
self.assertEqual(order.tax, 6.40)
self.assertEqual(order.total, 86.40)



این تست معنی نداره — داره چیز بدیهی رو تست می‌کنه

class PostModelTest(TestCase):
def test_post_has_noscript(self):
post = Post.objects.create(noscript='Test')
self.assertEqual(post.noscript, 'Test') # بی‌فایده



قاعده‌ی من:
به اندازه‌ای تست بنویس که آخر جمعه عصر بدون استرس دیپلوی کنی.

پ.ن: یادتون نره پستا رو با دوستاتون به اشتراک بذارید ❤️❤️

پارت اول ۲۰ سوال جنگو
پارت دوم ۲۰ سوال جنگو
پارت سوم ۲۰ سوال جنگو
پارت چهارم ۲۰ سوال جنگو
پارت پنجم ۲۰ سوال جنگو
پارت ششم ۲۰ سوال جنگو
پارت هفتم ۲۰ سوال جنگو

#پارت_هشتم #جنگو #django #پایتون #برنامه_نویسی

@PhiloLearn
👌4
شما هم ؟؟ 😂😂😂🤦🏻‍♂️

#fun@PhiloLearn
👍4👎32
UV در پایتون: سریع‌ترین مدیر پکیج و پروژه (راهنمای کامل + پروژهٔ نمونه)

پکیج منیجمنت پایتون بلاخره اون ارتقای درست و درمونی که لیاقتش داشت رو دریافت کرد. میخوام شما رو با UV آشنا کنم؛ مدیر پکیج و پروژه ی فوق سریع و مبتنی بر RUST که توسط Astral (تیم سازنده Ruff (لینتر خیلی سریع پایتون)) ساخته شده. اگر تا الان پیش اومده که آرزو کرده باشید که pip، virtualenv، pipx، pyenv و pip-tools تو یک ابزار خلاصه بشه.. خب UV دقیقا همون چیزیه که دنبالش بودید.
اگر همچین آرزویی نداشتید هم به من اعتماد کنید، قطعا اون آرزوییه که خودتون نمیدونید دارید.

`uv` چیست؟

‌‏`uv` یک مدیر پکیج و پروژهٔ پایتون با عملکرد بالا است — و جایگزینی مدرن برای:
‏- pip
‏- virtualenv
‏- pipx
‏- pyenv
‏- pip-tools
- و حتی ابزارهای ساخت اسکلت پروژه

همه در قالب یک ورکفلوی یکپارچه.

بهش اینطور نگاه کنید که:
مدیریت محیط Conda + نصب وابستگی‌های Pip + لایف سایکل Poetry. اما ۱۰ برابر سریع‌تر.


امکانات:
- ایجاد پروژه
- لاک‌فایل‌ها
- محیط مجازی خودکار
- نصب نسخه‌های مختلف پایتون
- اجرای فرمان‌ها در محیط ایزوله
- ساخت و انتشار پکیج‌ها
- نصب ابزارهای CLI به‌صورت سراسری

‏نصب `uv`

macOS / Linux

curl -LsSf https://astral.sh/uv/install.sh | sh


Windows (PowerShell)

powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"


تأیید نصب:

uv --version


تمام. شما آماده‌اید.

پ.ن: یادتون نره پست رو با دوستاتون به اشتراک بذارید ❤️❤️

#پارت_اول #python #uv #virtualenv #tutorial #پایتون #آموزش_پایتون #برنامه_نویسی


@PhiloLearn
3
درک نحوه ی کارکرد uv
‏`uv` حول چند ایده ی اصلی طراحی شده:

1. ایجاد خودکار محیط پروژه

وقتی اجرا کنید:

uv run python noscript.py


به صورت خودکار یک .venv ایجاد می‌کند و آن را مدیریت می‌کند.

2. لاک‌فایل برای تکرارپذیری


uv lock


یک مجموعه کاملاً قابل تکرار از نسخه‌های پکیج می‌سازد.

3. مدیریت نسخهٔ پایتون

‏uv می‌تواند نسخه‌های مختلف پایتون را دانلود و مدیریت کند (مثل pyenv).

4. سرعت

همه‌چیز با Rust نوشته شده. حل وابستگی‌ها، نصب، ساخت محیط — همه فوق‌العاده سریع.

پارت اول UV

پ.ن: یادتون نره پست رو با دوستاتون به اشتراک بذارید ❤️❤️

#پارت_دوم #python #uv #virtualenv #tutorial #پایتون #آموزش_پایتون #برنامه_نویسی

@PhiloLearn
3
راهنمای کامل فرمان‌های uv

1. ایجاد پروژه
ساخت یک پروژه جدید پایتون:

uv init --type application


این دستور ایجاد می‌کند:

- فایل pyproject.toml
- یک پوشهٔ src پایه
- اطلاعات متادیتا برای مدیریت وابستگی‌ها


2. افزودن وابستگی‌ها
افزودن پکیج‌های runtime

uv add fastapi uvicorn
uv add "requests>=2.30"


افزودن وابستگی‌های توسعه

uv add --dev pytest black ruff


حذف وابستگی

uv remove requests



3. لاک و همگام‌سازی (محیط‌های تکرارپذیر)
ساخت لاک‌فایل

uv lock


نصب تمام وابستگی‌ها داخل .venv

uv sync


این دو دستور تضمین می‌کنند همهٔ توسعه‌دهندگان دقیقاً یک محیط مشابه داشته باشند.


4. اجرای همه‌چیز با uv
اجرای پایتون یا هر CLI داخل محیط پروژه

uv run python main.py
uv run pytest
uv run uvicorn app.main:app --reload


اجرا با نسخهٔ مشخص پایتون

uv run --python 3.10 noscript.py



5. نصب نسخه‌های پایتون
uv python install 3.12
uv python list



‏6. uv pip : جایگزین سریع pip
uv pip دقیقاً مثل pip رفتار می‌کند، فقط سریع‌تر.

مثال‌ها:

uv pip install httpx
uv pip uninstall httpx
uv pip list
uv pip freeze
uv pip install -r requirements.txt



7. نصب ابزارهای سراسری (مشابه pipx)
uv tool install nox[uv]
uv tool install httpie


یا اجرای ابزار بدون نصب:

uvx pycowsay "hello world"



8. ساخت و انتشار
ساخت wheel و سورس‌دیست:

uv build


انتشار در PyPI:

uv publish


پارت اول UV
پارت دوم UV

پ.ن: یادتون نره پست رو با دوستاتون به اشتراک بذارید ❤️❤️

#پارت_سوم #python #uv #virtualenv #tutorial #پایتون #آموزش_پایتون #برنامه_نویسی

@PhiloLearn
3👍1
پروژهٔ نمونه: ساخت FastAPI با uv

یک پروژهٔ واقعی FastAPI فقط با uv بسازیم.

مرحله ۱ — ایجاد پروژه
mkdir myfastapi && cd myfastapi
uv init --type application


مرحله ۲ — افزودن وابستگی‌ها
uv add fastapi uvicorn
uv add --dev pytest black ruff


مرحله ۳ — ساخت اپ FastAPI
فایل app/main.py را بسازید:
from fastapi import FastAPI

app = FastAPI()

@app.get("/")
async def root():
return {"message": "Hello from uv + FastAPI!"}


مرحله ۴ — لاک و همگام‌سازی
uv lock
uv sync


مرحله ۵ — اجرای API

uv run uvicorn app.main:app --reload --port 8000


باز کردن در مرورگر:

http://127.0.0.1:8000

نمایش:

{"message": "Hello from uv + FastAPI!"}



پارت اول UV
پارت دوم UV
پارت سوم UV

پ.ن: یادتون نره پست رو با دوستاتون به اشتراک بذارید ❤️❤️

#پارت_چهارم #python #uv #virtualenv #tutorial #پایتون #آموزش_پایتون #برنامه_نویسی

@PhiloLearn
2
چرا باید همین امروز از uv استفاده کنید؟

یک ابزار به‌جای پنج ابزار

دیگر نیاز نیست با pip، venv، pyenv، pipx و poetry درگیر شوید.

سریع. واقعاً سریع.
‏نصاب و حل‌کننده Rust = سرعت باور نکردنی.

قابل‌تکرار

‏لاک‌فایل + sync کار تیمی و CI/CD را بدون دردسر می‌کند.

طراحی‌شده برای پایتون مدرن

‏PEP 517/518، معماری pyproject-first، متادیتای تمیز.

سازگار با هر جریان کاری
‌‏FastAPI، Django، پروژه‌های ML، ابزارهای CLI - همه‌چیز.



در نهایت پیشنهادم اینه که دفعه ی بعدی که خواستید یک پروژه ی پایتونی رو استارت بزنید، حتما کار با UV رو امتحان کنید. یه حسی بهم میگه اصلا از این کار پشیمون نخواهید شد.

پارت اول UV
پارت دوم UV
پارت سوم UV
پارت چهارم UV

پ.ن: یادتون نره پست رو با دوستاتون به اشتراک بذارید ❤️❤️

#پارت_پنجم #python #uv #virtualenv #tutorial #پایتون #آموزش_پایتون #برنامه_نویسی

@PhiloLearn
2
Forwarded from محتوای آزاد سهراب (Sohrab)
توی این ویدئو رفتیم سراغ دستور pwd تا ببینیم دقیقاً چی‌کار می‌کنه و یک پیاده‌سازی ساده از اون رو داخل سی پلاس پلاس (بله سی پلاس پلاس) انجام دادیم.


تماشا از یوتوب



تماشا از پیرتوب


@SohrabContents
3
😂🤦🏻‍♂️😂🤦🏻‍♂️😂🤦🏻‍♂️

#fun@PhiloLearn
👍3👎2
درسته که ۲۰۲۵ سال لینوکس دسکتاپ نبود ولی
۲۰۲۶ دیگه واقعا قراره سال لینوکس دسکتاپ باشه...

#fun@PhiloLearn
3
یه لایبر بامزه‌ ی GUI پایتونی پیدا کردم به اسم PyWebview.

خیلی ساده بگم:
‏PyWebview یه جور wrapper کوچیک و خلوته که میاد یه پنجره سبک برایت باز می‌کنه و داخلش HTML/CSS/JS خودت رو می‌ذاری. نه الکترونه که رم سیستم رو بخوره، نه پیچیدگی فریم‌ورک‌های UI رو داره.
بکند پایتون + مرورگر خلوت = اپ دسکتاپ تمیز.

چرا باید ازش خوشت بیاد؟
- چون واقعا سبکه.
- چون اتصال پایتون به فرانت خیلی راحته.
- چون روی ویندوز، لینوکس و مک نیتو اجرا میشه.
- و بهترین بخش: دقیقا همون چیزی رو بهت می‌ده که لازم داری، بدون خزعبلات اضافه.

برای نصب؟

pip install pywebview



اولین کدتون:

import webview

window = webview.create_window("PyWebview Demo", html="<h1>Hello World!</h1>")
webview.start()


یه پنجره باز می‌شه، همین‌قدر ساده و بی‌دردسر.


لینک:
https://pywebview.flowrl.com

#ابزار #پایتون

💙💙 @PhiloLearn 💙💙
👍2
۹. از User مدل پیش‌فرض Django استفاده کنم یا یه User سفارشی بسازم؟

جواب کوتاه:
با همون User پیش‌فرض شروع کن. برای پروژه‌ی بعدیت برو سمت User سفارشی.



🟢 چه زمانی از User پیش‌فرض استفاده کنیم؟
- وقتی یک پروژه جدید رو شروع می‌کنی
- وقتی همون حالت عادی username/email/password برات کافیه
- وقتی داری پروتوتایپ می‌سازی
- وقتی می‌تونی با یه Profile مدل اضافی امکانات بیشتر اضافه کنی


🔵 چه زمانی User سفارشی لازم داریم؟
- وقتی می‌خوای ورود فقط با ایمیل باشه (بدون username)
- وقتی فیلدهای کاربر خیلی متفاوتن
- وقتی از همون اول پروژه این تصمیم رو گرفتی (بعداً تغییر دادنش سخت می‌شه)


اگر الان داری از User پیش‌فرض استفاده می‌کنی:

# توسعه User با OneToOne Profile
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
bio = models.TextField()
avatar = models.ImageField()
phone = models.CharField(max_length=20)

# دسترسی
user.profile.bio

این روش ۹۰٪ مواقع کافیه و دردسرهای Custom User رو هم نداره.


اگر از صفر داری شروع می‌کنی و User سفارشی می‌خوای:

# User سفارشی با ورود ایمیلی
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin

class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(unique=True)
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)

USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['first_name', 'last_name']


settings.py :

AUTH_USER_MODEL = 'core.User'



قانون من:

اگر شک داری، اصلاً سمت User سفارشی نرو. همون User پیش‌فرض + مدل Profile بهترین انتخابه.

پ.ن: یادتون نره پستا رو با دوستاتون به اشتراک بذارید ❤️❤️

پارت اول ۲۰ سوال جنگو
پارت دوم ۲۰ سوال جنگو
پارت سوم ۲۰ سوال جنگو
پارت چهارم ۲۰ سوال جنگو
پارت پنجم ۲۰ سوال جنگو
پارت ششم ۲۰ سوال جنگو
پارت هفتم ۲۰ سوال جنگو
پارت هشتم ۲۰ سوال جنگو

#پارت_نهم #جنگو #django #پایتون #برنامه_نویسی

@PhiloLearn
2
دقت کردید که برنامه نویسا عجیب و غریبن؟ چون زبانی که باهاش حرف میزنن عجیب و غریبه 😂😂

#fun@Philolearn
👍6👎1
۱۰. بهترین روش برای مدیریت آپلود فایل در Django چیه؟

جواب کوتاه:
از FileField استفاده کن و برای محیط واقعی (production) فایل‌ها رو روی S3 یا Google Cloud Storage بذار.



🟢 برای پروژه‌های کوچیک (کمتر از ۱۰۰۰ کاربر)

‎# ذخیره فایل روی فایل‌سیستم لوکال
class Document(models.Model):
file = models.FileField(upload_to='documents/')



سرو کردن فایل‌ها با nginx:

location /media/ {
alias /var/www/myproject/media/;
}


این روش برای توسعه و پروژه‌های کوچیک کاملاً اوکیه.


🔵 برای پروداکشن (Production)

برو سراغ django-storages + S3

# settings.py
INSTALLED_APPS += ['storages']

AWS_ACCESS_KEY_ID = os.environ['AWS_ACCESS_KEY_ID']
AWS_SECRET_ACCESS_KEY = os.environ['AWS_SECRET_ACCESS_KEY']
AWS_STORAGE_BUCKET_NAME = 'mybucket'
AWS_S3_CUSTOM_DOMAIN = f'{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com'

DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'



مدل تغییری نمی‌کنه:

class Document(models.Model):
file = models.FileField(upload_to='documents/')



و Django خودش آپلود به S3 رو هندل می‌کنه:

document = Document.objects.create(file=request.FILES['file'])




🔒 نکات امنیتی

۱. نوع فایل رو چک کن

from django.core.exceptions import ValidationError

def validate_file_extension(value):
allowed = ['.pdf', '.doc', '.docx']
ext = os.path.splitext(value.name)[1]
if ext.lower() not in allowed:
raise ValidationError('Unsupported file type')

class Document(models.Model):
file = models.FileField(
upload_to='documents/',
validators=[validate_file_extension]
)



۲. اندازه فایل رو محدود کن

class DocumentForm(forms.ModelForm):
class Meta:
model = Document
fields = ['file']

def clean_file(self):
file = self.cleaned_data['file']
if file.size > 10 * 1024 * 1024: # 10MB
raise ValidationError('File too large (max 10MB)')
return file




قانون من:

برای توسعه و تست از فایل‌سیستم لوکال استفاده کن. برای پروڈاکشن S3 بهترین انتخابه.


پ.ن: یادتون نره پستا رو با دوستاتون به اشتراک بذارید ❤️❤️

پارت اول ۲۰ سوال جنگو
پارت دوم ۲۰ سوال جنگو
پارت سوم ۲۰ سوال جنگو
پارت چهارم ۲۰ سوال جنگو
پارت پنجم ۲۰ سوال جنگو
پارت ششم ۲۰ سوال جنگو
پارت هفتم ۲۰ سوال جنگو
پارت هشتم ۲۰ سوال جنگو
پارت نهم ۲۰ سوال جنگو

#پارت_دهم #جنگو #django #پایتون #برنامه_نویسی

@PhiloLearn
2
Forwarded from FuckingProgrammingBook
چاپ سوم این راهنمای معتبر، کاربرد عملی توسعه آزمون‌محور (TDD) در ساخت برنامه‌های وب واقعی با پایتون را نشان می‌دهد. شما می‌آموزید که چگونه با نوشتن آزمون‌ها قبل از هر بخش کد و سپس نوشتن حداقل کد لازم برای عبور از آن‌ها، به نرم‌افزاری تمیز، قابل اعتماد و با قابلیت نگهداری بالا دست یابید. این کتاب که برای پایتون ۳.۱۱ و جنگو ۴ به‌روز شده، با بیانی عملی و مثال‌محور، مبانی جنگو، سلنیوم، جاوااسکریپت، Git و Mock Objects را آموزش داده و نشان می‌دهد TDD چگونه طراحی ساده‌تر و اطمینان بیشتر به کد را به ارمغان می‌آورد. مباحث کلیدی شامل گردش کار کامل TDD، نوشتن آزمون واحد و عملکردی، mock objects، استقرار خودکار با Docker، تست در محیط stage، یکپارچه‌سازی مستمر (CI) و ساخت REST API با رابط جاوااسکریپت می‌شود.

لینک کتاب


#book

@FuckingProgrammingBooks

📚📚 @PhiloLearn 📚📚
👍1
پیشنهاد و انتقاد و درخواستی اگر داشتید، دایرکت کانال @PhiloLearn درش به روی همه ی شما عزیزان بازه 💙💙
1
هر وقت حس بی مصرف بودن کردید، مایکروسافت ایج برای لینوکس رو به خاطرتون بیارید 😂😂😂

#fun@PhiloLearn
🤣11👎21
سوال ساده:
چرا معمولا توی لوپ ها از i استفاده می‌کنن ؟؟

@PhiloLearn
Forwarded from Linuxor ?
آقای Geoffrey Hinton، معروف به پدرخوانده AI، یه هشدار داده که اگه فکر می‌کنین با رشد سریع هوش مصنوعی بهتره رشته‌تون رو عوض کنین، دست نگه دارین. Computer Science فقط کدنویسی نیست، یادگیری سیستم‌ها، ریاضی و حل مسئله مهارت‌هایی هستن که AI هیچ وقت نمی‌تونه کامل جایگزینشون بشه.

حتی اگه AI داره خیلی از کارای برنامه‌نویسی رو انجام می‌ده، داشتن پایه قوی توی CS هنوز ارزش داره و کمک می‌کنه که بتونین نوآوری کنین و مهارت‌هاتون رو به سطح بعدی برسونین. Hinton حتی توصیه کرده کدنویسی رو یاد بگیرین؛ مثل خوندن لاتین، شاید مستقیم استفاده نکنین ولی مغزتون رو قوی می‌کنه.

@Linuxor
1
۱۱. چطور یک پروژه بزرگ Django رو ساختاردهی کنم؟

جواب کوتاه:
بر اساس ویژگی (Feature) ساختار بده، نه بر اساس لایه (models/views/serializers).


ساختار بد (بر اساس لایه)

myproject/
├── models/
│ ├── user.py
│ ├── post.py
│ └── comment.py
├── views/
│ ├── user_views.py
│ ├── post_views.py
│ └── comment_views.py
├── serializers/
│ ├── user_serializers.py
│ ├── post_serializers.py
│ └── comment_serializers.py
└── ...


مشکل:
برای فهمیدن یه فیچر باید بین ۵ تا فایل بپری. سرعتت افتضاح می‌شه.

ساختار خوب (بر اساس فیچر)

myproject/
├── users/
│ ├── models.py
│ ├── views.py
│ ├── serializers.py
│ ├── urls.py
│ └── tests.py
├── posts/
│ ├── models.py
│ ├── views.py
│ ├── serializers.py
│ ├── urls.py
│ └── tests.py
└── core/
├── utils.py
├── middleware.py
└── base_models.py


اینجوری هر فیچر همه فایل‌های مربوط به خودش رو داره.
خوانایی بالا می‌ره و نگهداری راحت‌تر می‌شه.


🟦 برای پروژه‌های خیلی بزرگ

وقتی هر app خیلی گنده شد، می‌تونی داخلش فولدرهای لایه‌ای بسازی:

myproject/
├── users/
│ ├── models/
│ │ ├── user.py
│ │ ├── profile.py
│ │ └── permissions.py
│ ├── views/
│ │ ├── auth.py
│ │ ├── profile.py
│ │ └── admin.py
│ ├── serializers/
│ ├── tests/
│ └── urls.py
└── ...


این ساختار برای تیم‌های بزرگ یا پروژه‌های enterprise عالیه.


قانون من:
کدی که با هم استفاده می‌شه باید کنار هم باشه.
اگه برای پیدا کردن یک فیچر باید اسکرول کنی یا بپری این‌ور و اون‌ور، ساختارت اشتباهه.

پ.ن: یادتون نره پستا رو با دوستاتون به اشتراک بذارید ❤️❤️

پارت اول ۲۰ سوال جنگو
پارت دوم ۲۰ سوال جنگو
پارت سوم ۲۰ سوال جنگو
پارت چهارم ۲۰ سوال جنگو
پارت پنجم ۲۰ سوال جنگو
پارت ششم ۲۰ سوال جنگو
پارت هفتم ۲۰ سوال جنگو
پارت هشتم ۲۰ سوال جنگو
پارت نهم ۲۰ سوال جنگو
پارت دهم ۲۰ سوال جنگو

#پارت_یازدهم #جنگو #django #پایتون #برنامه_نویسی

@PhiloLearn
6
PhiloLearn | فیلولرن
def validate_file_extension(value):
allowed = ['.pdf', '.doc', '.docx']
ext = os.path.splitext(value.name)[1]
if ext.lower() not in allowed:
raise ValidationError('Unsupported file type')
دوستان توی کامنت ها اشاره کردن که این روش درستی نیست و خب حق با ایشان است. اینکار میتونه خطرات خیلی زیادی هم به همراه داشته باشه.
اگر خواستید نوع فایل رو چک کنید راه های به نسبت امن تر و بهینه تر زیادی هست.
مثلا شما میتونید خودتون Head فایل رو چک کنید یا از libmagic و لایبری پایتون python-magic استفاده کنید که استفاده ازش هم خیلی راحته.

مثال:
>>> import magic
>>> magic.from_file("testdata/test.pdf")
'PDF document, version 1.2'
# recommend using at least the first 2048 bytes, as less can produce incorrect identification
>>> magic.from_buffer(open("testdata/test.pdf", "rb").read(2048))
'PDF document, version 1.2'
>>> magic.from_file("testdata/test.pdf", mime=True)
'application/pdf'


لینک pypi

#نکتک@PhiloLearn
5