برنامه نویسیپایتون

ویژگی ها و تکنیک های پایتون – بخش اول

ویژگی ها و تکنیک های پایتون – بخش اول

پایتون در حال حاضر جز محبوب ترین زبان های برنامه نویسی میباشد. متاسفانه بخاطر سادگی این زبان خیلی از افراد نکات مهمی از جمله یادگیری توابع و آبجکت های داخلی, کتابخانه های داخلی, و حتی سینتکس کامل آن قافل میشوند. در این پست قصد داریم ویژگی ها و تکینک های پایتون را به شما معرفی کنیم و بیشتر به سینتکس پایه و builtin ها می پردازیم.

لیست ویژگی ها و تکنیک ها در این بخش

  • توابع داخلی gettattr و setattr
  • ویژگی list unpacking و کاربردهای آن
  • ویژگی dictionary unpacking و کاربردهای آن

توابع داخلی getattr و setattr

تابع getattr با فرمت getattr(object, name[, default]) برای گرفتن attribute به نام name از object می باشد.

آرگومان object میتواند از هر نوع داده ای باشد چرا که در پایتون تقریبا همه چیز شئ هستند. name باید از نوع string باشد و default میتواند هر نوعی باشد و همینطور اختیاری است و اگر مقداری به آن داده نشود و attribute ای به نام مشخص شده در name در آن object وجود نداشته باشد خطای AttributeError رخ میدهد. برای چک کردن وجود attribute ای به نام name در object میتوانید از تابع hasattr استفاده کنید.

تابع setattr نیز مانند getattr میباشد اما برای تنظیم attribute با نام name بر روی object با مقدار value میباشد و فرمت آن setattr(object, name, value) است.

مثال:

#!/usr/bin/env python3

class Example(object):
CONSTANT = "test"

def __init__(self, x, y):
self.x = x
self.y = y

def f1(self):
return x * y

def f2(self):
return (x + y) * 2

if __name__ == "__main__":
# direct use to get `CONSTANT` attribute
# NOTE if this attribute doesn't exist,
# it will raise an AttributeError exception
# this will print "test"
print(Example.CONSTANT)

# get attribute `CONSTANT`, if it doesn't exist,
# it will return None
# this will print "test"
print(getattr(Example, "CONSTANT"))

# if attribute doesn't exist, getattr will return "unknown"
# this will print "unkown"
print(getattr(Example, "distance", "unknown"))

# set attribute `distance` on class Example
setattr(Example, "distance", 200)

# this will print "200"
print(Example.distance)

# this also will print "200"
print(getattr(Example, "distance", "unknown"))

خروجی مثال:

$ python3 getattr_setattr_example.py
test
test
unknown
۲۰۰
۲۰۰

عمده استفاده ای که شخصا از این توابع داشته ام در مواقع نیاز به metaprogramming بوده است.

ویژگی list unpacking و کاربردهای آن

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

ارسال و دریافت تعداد نامشخصی از آرگومان:

def func1(s, *args):
for arg in args:
print(s, arg)

def func2(a, b, c):
return a * b * c

if __name__ == "__main__":
# send unpacked, recive packed
func1("func1(..., 10, 20, 30) :", 10, 20, 30)

# send packed, recieve packed
args1 = [1, 2, 3, 4, 5, 6]
func1("func1(..., *args1) :", *args1)

# send packed, recive unpacked
args2 = [2, 2, 2]
print("func2(*args2) :", func2(*args2))

func1(..., 10, 20, 30) : 10
func1(..., 10, 20, 30) : 20
func1(..., 10, 20, 30) : 30
func1(..., *args1) : 1
func1(..., *args1) : 2
func1(..., *args1) : 3
func1(..., *args1) : 4
func1(..., *args1) : 5
func1(..., *args1) : 6
func2(*args2) : 8

اجبار کردن به استفاده از مدل keyword argument برای آرگومان های اختیاری:

#!/usr/bin/env python3

def area(x, y=None, z=None, *, debug=False):
if debug:
if z is not None:
print("func1 : 3d request")
elif y is not None and x != y:
print("func1 : rectangle request")
else:
print("func1 : square request")

print("area =", x * (y or 1) * (z or 1))

if __name__ == "__main__":
# square
area(3)

# square with debug
area(3, debug=True)

# rectangle
area(3, 2)

# rectangle with debug
area(3, 2, debug=True)

# ۳d
area(3, 2, 3)

# ۳d with debug
area(3, 2, 3, debug=True)

# function area only accepts 3 positional arguments,
# the * notation will prevent function calls to define
# `debug` arguments by positional argumenting.
#
# NOTE this will through a TypeError
area(3, 3, 3, 3, 3, 3, 3, *([3]*200), debug=True)

area = 3
func1 : square request
area = 3
area = 6
func1 : rectangle request
area = 6
area = 18
func1 : 3d request
area = 18
Traceback (most recent call last):
File "list_unpacking_force_keywords.py", line 38, in <module>
area(3, 3, 3, 3, 3, 3, 3, *([3]*200), debug=True)
TypeError: area() takes from 1 to 3 positional arguments but 207 positional arguments (and 1 keyword-only argument) were given

ویژگی dictionary unpacking و کاربردهای آن

این ویژگی نیز درست مانند list unpacking میباشد. با این تفاوت که بر روی دیکشنری ها و آرگومان های کلیدی یا همان keyword arguments کار میکند.

مثال:

def print_args(*args, prefix=" [*]", **kwargs):
for i, arg in enumerate(args):
print("%s ARG:%d => %s" % (prefix, i, str(arg)))

for key, value in kwargs.items():
print("%s KWARG:(%s) => %s" % (prefix, str(key), str(value)))

def server_config_automation(user, password, **configs):
# connect to server...
# parse configs...
# apply...
# etc...
pass

if __name__ == "__main__":
print_args("someone", "some arg", someone="me?", some_arg="oh!")
print_args("possible?", prefix=" [PARSER]", possible="yes!")

# not real world really, you might want to use
# puppet, chef, ansible, etc..
# and also no one keeps data in code...

creds = {
"username": "someone",
"password": "something"
}

config = {
"deploy" : {
"pid": "/var/run/app.pid",
"log": "/var/logs/app/logs.txt",
"hosts": [
"example.ir", "example.com", "localhost",
"۱۲۷٫۰٫۰٫۱"
],
"port": 80,
# ....
},
"dev" : {
# ....
},
"proxy" : {
# ....
},
# ....
}

server_config_automation(
creds['username'],
creds['password'],
**(config['deploy'])
)

[*] ARG:0 => someone
[*] ARG:1 => some arg
[*] KWARG:(someone) => me?
[*] KWARG:(some_arg) => oh!
[PARSER] ARG:0 => possible?
[PARSER] KWARG:(possible) => yes!

در پست بعدی؟

در پست بعدی به string format و قابلیت های جدید معرفی شده در پایتون ۳.۸ خواهیم پرداخت.

موفق و پیروز باشید.

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا