Yeni Veri Tipi Tanımlama

Merhaba,

TL adında yeni bir veri tipi tanımlamaya çalıştım;
Fakat, sorun şu ki; TL'den, int'e çevirirken ‘₺’ karakteri, sorun çıkarıyor.

Bunu, -sınıf içinde- nasıl ayarlayabilirim?

Kod:

class TL(float):
  def __new__(self, *args, **kwargs):
    return f"₺ {super().__new__(self, *args, **kwargs)}"

i  = 100
print(i)

tl = TL(i)
print(tl)

r_i  = int(tl)
print(r_i)

Hata:

100
₺ 100.0
Traceback (most recent call last):
  File "<string>", line 11, in <module>
ValueError: invalid literal for int() with base 10: '₺ 100.0'

Not: = ₺

__new__, TL örneği döndürmediği için sınıfın hiçbir anlamı yok. tl değişkeninin tipi TL değil, str. __new__, bir TL örneği döndürürse miras alınan float sınıfı zaten __int__ metodunu sağlar. Örnekleri ekrana yazmak için de __repr__ metodu lazım.

Niye kendi __new__ metodunuzu yazıyorsunuz?

1 Beğeni

Hmm… bunu basit bir örnek ile biraz açar mısınız?


Aynısını __init__() ile denedim, ama “__init__(), sadece None döndürmeli” gibi bir hata verdiği için __new__() ile denedim.

Dedikleriniz üzere birkaç deneme yaptım ve sanırım başardım.

Kod:

class TL(float):
  def __init__(self, x):
    super().__init__()
    self.x = x

  def __repr__(self):
    return f"₺ {self.x}"

i  = 100
print(i)

tl = TL(i)
print(tl)

print(type(tl))

r_i  = int(tl)
print(r_i)

Çıktı:

100
₺ 100
<class '__main__.TL'>
100

Niye None dışında bir şey döndürmeye ihtiyacınız var?

Amacınıza ulaşmışsınız ama yöntem pek doğru durmuyor. Eğer girilen sayı (x) bir nitelik olarak saklanacaksa float’ı miras almaya gerek yok:

class TL():
    def __init__(self, x):
        self.x = x

    def __int__(self):
        return int(self.x)

    def __float__(self):
        return float(self.x)

    def __repr__(self):
        return f"₺ {self.x}"

float miras alınacaksa da x’e gerek yok:

class TL(float):

    def __repr__(self):
        return f"₺ {super().__repr__()}"

Bir de şimdi koda bakınca hatırladım: __repr__ daha çok debug amaçlı kullanılıyor, bu örnekte __repr__'leri __str__ ile değiştirmek daha doğru olur.

Aslında biraz daha uğraşıp, şöyle birşey yapmıştım;

def __init__(self, x=float()):
    super().__init__()
    self.x = x

  def __str__(self):
    if not isinstance(self.x, TL):
      return f"₺ {self.x}"

    else:
      return f"{self.x}"

Ama şu kadarı bile işimi gördü:

class TL(float):
  def __str__(self):
    return f"₺ {super().__repr__()}"

Peki bunu sözdizimine dahil etmenin bir yolu varmı?
Mesela,

>>> x = ₺123.0 #veya TL123.0
>>> type(x)

<class '__main__.TL'>

Bu kodda da şu geçerli:

__str__ kısmını da anlamadım.


Yok.

1 Beğeni

Peki, teşekkür ederim :slight_smile: