Kurs
Bu eğitimdeki kodu çevrimiçi olarak çalıştırın ve düzenleyin
Kodu çalıştırBirçok Python geliştiricisi, Python’daki alt çizgi (_) işlevlerinden habersizdir. Bu karakter, kullanıcıların Python kodunu daha verimli yazmasına yardımcı olur.
Alt çizgi (_), Python’da özel bir karakterdir.
Eğer bir Python programcısıysanız, muhtemelen aşağıdaki sözdizimine aşinasınızdır:
-
for _ in range(100)
-
__init__(self)
- _ = 2
Farklı durumlarda bazı özel anlamlara sahiptir. Gelin hepsine bakalım.
Alt çizgi (_) için en fazla altı farklı kullanım bulacaksınız. İsterseniz alt çizgi (_) hakkında fikir edindikten sonra farklı amaçlarla da kullanabilirsiniz.
1. Yorumlayıcıda Kullanım
Python, yorumlayıcıda son ifadenin değerini otomatik olarak "_" adlı özel bir değişkende saklar. İsterseniz bu değeri başka bir değişkene de atayabilirsiniz.
Onu normal bir değişken gibi kullanabilirsiniz. Örneğe bakın
>>> 5 + 4
9
>>> _ # stores the result of the above expression
9
>>> _ + 6
15
>>> _
15
>>> a = _ # assigning the value of _ to another variable
>>> a
15
2. Değerleri Yoksayma
Alt çizgi (_) değerleri yoksaymak için de kullanılır. Açmayı (unpacking) yaparken belirli değerleri kullanmak istemiyorsanız, o değeri alt çizgi (_) değişkenine atayın.
Yoksaymak, değerleri özel alt çizgi (_) değişkenine atamak anlamına gelir. Gelecekteki kodda kullanılmayacağı için verilen değerleri alt çizgi (_) değişkenine atıyoruz.
Örneğe bakın
## ignoring a value
a, _, b = (1, 2, 3) # a = 1, b = 3
print(a, b)
## ignoring multiple values
## *(variable) used to assign multiple value to a variable as list while unpacking
## it's called "Extended Unpacking", only available in Python 3.x
a, *_, b = (7, 6, 5, 4, 3, 2, 1)
print(a, b)
1 3
7 1
3. Döngülerde Kullanım
Döngülerde alt çizgi (_)yi değişken olarak kullanabilirsiniz. Fikir edinmek için aşağıdaki örneklere bakın.
## lopping ten times using _
for _ in range(5):
print(_)
## iterating over a list using _
## you can use _ same as a variable
languages = ["Python", "JS", "PHP", "Java"]
for _ in languages:
print(_)
_ = 5
while _ < 10:
print(_, end = ' ') # default value of 'end' id '\n' in python. we're changing it to space
_ += 1
0
1
2
3
4
Python
JS
PHP
Java
5 6 7 8 9
4. Sayı Basamaklarını Ayırma
Uzun basamaklı bir sayınız varsa, daha iyi anlaşılması için basamak gruplarını dilediğiniz gibi ayırabilirsiniz.
Örn:- million = 1_000_000
Ayrıca, sayıların ikili (binary), sekizli (octal) veya onaltılı (hex) kısımlarını ayırmak için de alt çizgi (_) kullanabilirsiniz.
Örn:- binary = 0b_0010, octa = 0o_64, hexa = 0x_23_ab
Sonuçları görmek için yukarıdaki örneklerin hepsini çalıştırın.
## different number systems
## you can also check whether they are correct or not by coverting them into integer using "int" method
million = 1_000_000
binary = 0b_0010
octa = 0o_64
hexa = 0x_23_ab
print(million)
print(binary)
print(octa)
print(hexa)
1000000
2
52
9131
5. Alt Çizgi (_) ile Adlandırma
Alt çizgi (_) değişken, fonksiyon ve sınıf vb. adlandırmalarında kullanılabilir.
- Tek Ön Ek Alt Çizgi:- _variable
- Tek Son Ek Alt Çizgi:- variable_
- Çift Ön Ek Alt Çizgi:- __variable
- Çift Ön ve Son Ek Alt Çizgi:- __variable__
5.1. _single_pre_underscore
_name
Tek ön ek alt çizgi dahili kullanım içindir. Çoğumuz bu nedenle kullanmayız.
Aşağıdaki örneğe bakın.
class Test:
def __init__(self):
self.name = "datacamp"
self._num = 7
obj = Test()
print(obj.name)
print(obj._num)
datacamp
7
Tek ön ek alt çizgi, tek ön ek alt çizgili değişkene erişmenizi engellemez.
Ancak, tek ön ek alt çizgi modülden içe aktarılan adları etkiler.
Aşağıdaki kodu my_funtions dosyasına yazalım.
## filename:- my_functions.py
def func():
return "datacamp"
def _private_func():
return 7
Şimdi, my_functions.py içindeki tüm yöntem ve adları import ederseniz, Python tek ön ek alt çizgi ile başlayan adları içe aktarmayacaktır.
>>> from my_functions import *
>>> func()
'datacamp'
>>> _private_func()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name '_private_func' is not defined
Yukarıdaki hatadan, modülü normal şekilde içe aktararak kaçınabilirsiniz.
>>> import my_functions
>>> my_functions.func()
'datacamp'
>>> my_functions._private_func()
7
Tek ön ek alt çizgi yalnızca dahili kullanım için tasarlanmıştır.
5.2 single_postunderscore
name_
Bazen Python Anahtar Sözcüklerini değişken, fonksiyon veya sınıf adı olarak kullanmak isterseniz, bunun için bu yaklaşımı kullanabilirsiniz.
Kullanmak istediğiniz adın sonuna bir alt çizgi ekleyerek Python Anahtar Sözcükleri ile çakışmaları önleyebilirsiniz.
Örneğe bakalım.
>>> def function(class):
File "<stdin>", line 1
def function(class):
^
SyntaxError: invalid syntax
>>> def function(class_):
... pass
...
>>>
Tek son ek alt çizgi, değişkenlerinizi Python Anahtar Sözcükleri gibi adlandırmak ve değişken adınızın sonuna bir alt çizgi ekleyerek çakışmaları önlemek için kullanılır.
5.3. Çift Ön Ek Alt Çizgi
__name
Çift ön ek alt çizgiler ad karıştırma (name mangling) için kullanılır.
Çift ön ek alt çizgiler, ad çakışmalarını önlemek için alt sınıfların öznitelik adlarını yeniden yazmasını Python yorumlayıcısına söyler.
- Ad karıştırma:- Python yorumlayıcısı, sınıf miras alındığında çakışmayı zorlaştıracak şekilde değişken adını değiştirir.
Bir örneğe bakalım.
class Sample():
def __init__(self):
self.a = 1
self._b = 2
self.__c = 3
obj1 = Sample()
dir(obj1)
['_Sample__c',
'__class__',
'__delattr__',
'__dict__',
'__dir__',
'__doc__',
'__eq__',
'__format__',
'__ge__',
'__getattribute__',
'__gt__',
'__hash__',
'__init__',
'__init_subclass__',
'__le__',
'__lt__',
'__module__',
'__ne__',
'__new__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__setattr__',
'__sizeof__',
'__str__',
'__subclasshook__',
'__weakref__',
'_b',
'a']
Yukarıdaki kod, sınıf nesnesinin tüm özniteliklerini döndürür. Değişkenlerimizi öznitelik listesinde inceleyelim.
self.a değişkeni listede herhangi bir değişiklik olmadan görünür.
self._b değişkeni de listede herhangi bir değişiklik olmadan görünür. Yukarıda tartıştığımız gibi, bu yalnızca dahili kullanım içindir.
-
Listede self.__c değişkeni var mı?
- Öznitelik listesine dikkatle bakarsanız, _Sample__c adlı bir öznitelik bulursunuz. Bu, ad karıştırmadır. Alt sınıflarda değişkenin ezilmesini (overriding) önlemek içindir.
Ezmenin nasıl çalıştığını görmek için Sample sınıfını miras alan başka bir sınıf oluşturalım.
class SecondClass(Sample):
def __init__(self):
super().__init__()
self.a = "overridden"
self._b = "overridden"
self.__c = "overridden"
obj2 = SecondClass()
print(obj2.a)
print(obj2._b)
print(obj2.__c)
overridden
overridden
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-2-4bf6884fbd34> in <module>()
9 print(obj2.a)
10 print(obj2._b)
---> 11 print(obj2.__c)
AttributeError: 'SecondClass' object has no attribute '__c'
Burada ad karıştırma tekrar devreye girer. obj2.__c, _SecondClass__c olarak değiştirilir. Şimdi bu öğeyi değiştirilmiş öznitelik adıyla print edelim.
print(obj2._SecondClass__c)
overridden
Gördüğünüz gibi çalıştı; ayrıca önce oluşturulan değişkene _Sample__c kullanarak da erişebilirsiniz. Bakalım
print(obj1._Sample__c)
3
Çift ön ek alt çizgili değişkenlere sınıf içindeki yöntemler aracılığıyla da erişebilirsiniz. Bir örneğe bakalım.
class SimpleClass:
def __init__(self):
self.__datacamp = "Excellent"
def get_datacamp(self):
return self.__datacamp
obj = SimpleClass()
print(obj.get_datacamp()) ## it prints the "Excellent" which is a __var
print(obj.__datacamp) ## here, we get an error as mentioned before. It changes the name of the variable
Excellent
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-5-8006c0a9b061> in <module>()
9 obj = SimpleClass()
10 print(obj.get_datacamp()) ## it prints the "Excellent" which is a __var
---> 11 print(obj.__datacamp) ## here, we get an error as mentioned before. It changes the name of the variable
AttributeError: 'SimpleClass' object has no attribute '__datacamp'
Yöntem adları için de çift ön ek alt çizgi kullanabilirsiniz. Bir örneğe bakalım.
class SimpleClass:
def __datacamp(self):
return "datacamp"
def call_datacamp(self):
return self.__datacamp()
obj = SimpleClass()
print(obj.call_datacamp()) ## same as above it returns the Dobule pre underscore method
print(obj.__datacamp()) ## we get an error here
datacamp
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-1-cd8ce2e83589> in <module>()
9 obj = SimpleClass()
10 print(obj.call_datacamp()) ## same as above it returns the Dobule pre underscore method
---> 11 print(obj.__datacamp()) ## we get an error here
AttributeError: 'SimpleClass' object has no attribute '__datacamp'
Ad karıştırmaya başka bir açıdan bakalım. Önce _SimpleClass__name adlı bir değişken oluşturacağız, sonra bu değişkene çift ön ek alt çizgi adıyla erişmeyi deneyeceğiz.
Örneğe bakalım.
_SimpleClass__name = "datacamp"
class SimpleClass:
def return_name(self):
return __name
obj = SimpleClass()
print(obj.return_name()) ## it prints the __name variable
datacamp
Konsepti anladınız mı? Anlamadıysanız tekrar okumayı deneyin.
5.4. Çift Ön ve Son Ek Alt Çizgiler
__name__
Python’da, çift alt çizgi ile başlayıp biten farklı adlar görürsünüz. Bunlara büyülü yöntemler (magic methods) veya dunder yöntemleri denir.
class Sample():
def __init__(self):
self.__num__ = 7
obj = Sample()
obj.__num__
7
Bu yöntemleri değişken adları olarak kullanmanız çakışmalara yol açar. Bu yüzden onlardan uzak durmak daha iyidir.
Sonuç
Tebrikler! Başardınız. Python’daki en sıkıcı konseptlerden birini tamamladınız. Ancak ileri seviye kodlarla çalışırken çok faydalıdır.
Benim gibi çoğu kişi bu konsepti ilk okumada anlamaz. Bu yüzden sabrınızı kaybetmeyin; ilk seferde anlamadıysanız tekrar okuyun. Makaleyle ilgili herhangi bir şüpheniz varsa, yorum bölümünde belirtmekten çekinmeyin.
Eğer bir Python yeni başlayan iseniz, bu kursu almanızı ve ardından tam olarak anlamak için bu makaleyi tekrar okumanızı öneririm.
Kaynaklar:
