Node Master
1.02K subscribers
24 photos
2 files
156 links
Group Chat: @nodemastergp
Admin: @napoleon_n1
Download Telegram
من شخصا به عنوان یک #Python Hater دو آتیشه هستم.
ولی یک چیزی داره و عجیب خوب هست. حداقل من تا حالا شبیهش رو داخل هیچ اکوسیستم دیگه ای ندیدم و اگر شبیهش رو میشناسید معرفی کنید خوشحال میشم.

این ویژگی خیلی واقعا خفن pickle std برای #Python هست. در حقیقت pickle یک serialization format مثل #JSON هست و مثل #Protobuf یک فرمت binaray هست. حالا سوال پیش میاد چه نکته ای داره.
شما به pickel هر object در اکوسیستم #Python رو میتونید serialize کنید. هر Object با تمام پیچدگی ها custom که داره. بزارید با مثال توضیح بدم.
تصور کنید یک JSON دارید و اون رو میخواید map کنید به یک class و خب معمولا با Factory ها و به شکل های مختلف این اتفاق میافته.
class User {
constructor(name) {
this.name = name;
}
static FromJsonString(input) {
const result = JSON.parse(input);
return new User(result.name);
}
}

const runTimeInput = '{"name":"imanhpr"}';
const user = User.FromJsonString(runTimeInput);

console.log(user instanceof User);
console.log(user.name);


همه چی خیلی منطقی کار میکنه در این سناریو. نکته جالب که اینجا و توجه بهش جالبه این هست که در اینجا به صورت ذاتی هیچ metadata وجود نداره که مشخص بشه مقدار runTimeInput واقعا از جنس User هست و معمولا با استفاده از validation های مختلف و factory متد ها باید مشخص کنیم. اگر بخوایم یک سناریو دیگ رو برسی کنیم که یکم پیچیده تر باشه. شما به هردلیل منطقی یا غیرمنطقی تصمیم داری یک function که در نهایت یک object هست رو serialize کنید. چطور این کار میکنید؟
function hello() {
console.log("hooo");
}
console.log(JSON.stringify(hello));

باتوجه به این که در #JSON به طور کلی هیچ طوره فرمت استانداردی وجود نداره برای این کار منطقی هست کد بالا کار نکنه. ( البته با trick همین کد بالا رو میتونید کاری کنید که بشه ولی کاری به اون سناریو نداریم :) )
یک سناریو پیچیده تر اینه که شما یک object داشته باشید که property descriptor های اون رو دست کاری کردین چطور میخواین بدون ست کردن flag یا نشانه در هنگام serialize کردن و بعد از دریافت همون object متوجه بشید که property descriptor رو چطور باید ست کنید.

کلا بخوام خلاصه و جمع بندی کنم هرچیزی که مختص object هست که در runtime وجود داره مثل انواع reflection ها و property descriptor و method ها و ... .
اینجا هست که pickel خودش رو نشون میده.
import pickle

class NumberOne:
def __get__(self, obj, objtype=None) :
return 1


class User:
__name = "iman"
one = NumberOne()

@property
def name(self):
print("hello from getter")
return self.__name

def __eq__(self, value: object) -> bool:
if isinstance(value , User) and self.__name == value.__name:
return True
return False

def __str__(self) -> str:
return f'User(name={self.__name})'

def hello():
print("hello from function")

# instance sterilization
user_instance_bin = pickle.dumps(User())
run_time_user = pickle.loads(user_instance_bin)
print("user instanceof User :",isinstance(run_time_user , User))
print("user object :" , run_time_user)
print("equality check :" , run_time_user == User())
print("getter invocation :" , run_time_user.name)

# function sterilization
function_bin = pickle.dumps(hello)
run_timefn = pickle.loads(function_bin)
run_timefn()

# class sterilization
cls_bin = pickle.dumps(User)
runtime_cls = pickle.loads(cls_bin)
print("class check:" , issubclass(runtime_cls , User))

# << Exciting part >>
print("WTF:",run_time_user.one)

در اینجا شما هر جسم قابل لمسی رو در #Python میتونید serialize کنید و مستقیم با خوندن همون data یک object قابل لمس در runtime با تمام metadata ها دریافت کنید. از class گرفته تا یک gatter method که با decorator هست تا انواع magic method ها یا به قول #Pythonic ها dunder method.
از همه جالب تر اون بخش آخر هست که یک Python Descriptor رو هم کنار object های User گذاشتیم و میبینیم اون هم به صورت کامل میبینیم. اگر بخوام خلاصه در یک جمله توضیح بدم رسما با اینکار انگار از یک object دارید فایل exe میسازید به جای یک برنامه بزرگ!

نکته بعدی این که این pickel استاندارد مربوط به کد های python هست و جای دیگ تقریبا میشه گفت کاربردی نداره.

https://docs.python.org/3/library/pickle.html
👍5