Python Data Classes

Python  Linux  Programlama 

 18 Şubat 2019 - Türkiye



Follow
Follow
Follow

7 dakikalık okuma

Python 3.7 “Data Classes”

Data Classes

Python 3.7’deki yepyeni bir özellik “Data Classes” dır. “Data Classes” , birden fazla özellik barındıran sınıflar için klişe kod üretimini otomatikleştirmenin bir yoludur.

Ayrıca Python 3’ün yeni tür etiketlerini kullanmanın avantajını da taşıyorlar.

“Data Classes” Python 3.7’deki standart kitaplık içindeki “dataclasses” yeni veri sınıfları modülü ile sağlanır ve ihtiyacınız olacak 2 önemli şey içerir.

  1. Bir veri sınıfını dekore etmek için “dataclass decorator” süslü fonksiyonları
  2. Alanları yapılandırmak için “field” komut yordamı

Öntanımlı sihirli yordamlar

Varsayılan ayarla, herhangi bir dataclass init, repr, str ve eq komut yordamlarını sizin için uygulayacak.

init yordamı, sınıfta belirtilen aynı tip açıklamalarla anahtar sözcük ifadelerine sahip olacak.

The eq yordamı, tüm dataclass özniteliklerini sırayla karşılaştıracaktır.

Sınıfın üst kısmında gösterilen tüm alanlar ve tip gösterimi gereklidir.

from dataclasses import dataclass

@dataclass
class SimpleDataObject(object):
  '''
  In this case,
  __init__, __repr__, __eq__,  will all be generated automatically.
  '''
  
  field_a: int
  field_b: str

example = SimpleDataObject(1, 'b')
print(example)  # SimpleDataObject(field_a=1, field_b='b')

example2 = SimpleDataObject(1, 'b')
print(example == example2)  # True
SimpleDataObject(field_a=1, field_b=’b’)
True

Try it online!

Bu init yordamı (field_a: int, field_b: str) -> None şeklinde bir tanımlayıcıya sahip olabilir. Bunu sadece

print(inspect.signature(example.__init__))

yazarak görebilirsiniz.

Tip Gösterimi

Quite importantly, the type hints are merely hints. So giving the wrong types doesn’t issue a warning or attempt a conversion.

Because type hinting is required (otherwise the field is ignored), if you don’t have a specific type, use the Any type from the typing module.

from dataclasses import dataclass


@dataclass
class SimpleDataObject(object):
  '''
  In this case,
  __init__, __repr__, __eq__,  will all be generated automatically.
  '''
  
  field_a: int
  field_b: str

example = SimpleDataObject('a', 'b')
print(example)  # Gives SimpleDataObject(field_a='a', field_b='b')
SimpleDataObject(field_a=’a’, field_b=’b’)

Try it online!

Mutability

The dataclass decorator has a frozen argument, which is False by default. If specified, fields will be “frozen”, ie read-only and if eq is set to True, which it is by default then the hash magic will be implemented and object instances will be hashable so you can use them as dictionary keys or within a set.

from dataclasses import dataclass

@dataclass(frozen=True)
class ImmutableSimpleDataObject(object):
  '''
  In this case,
  __init__, __repr__, __lt__, __eq__, __gt__ will all be generated automatically.
  '''
  
  field_a: int
  field_b: str

example = {ImmutableSimpleDataObject(1, 'b'), ImmutableSimpleDataObject(2, 'c')}
print(example)

# Gives : {ImmutableSimpleDataObject(field_a=1, field_b='b'), ImmutableSimpleDataObject(field_a=2, field_b='c')}
{ImmutableSimpleDataObject(field_a=2, field_b=’c’), ImmutableSimpleDataObject(field_a=1, field_b=’b’)}

Try it online!

Customizing the fields

The core type in dataclasses is the Field type, which belongs to a dataclass.

By default, just setting a class attribute will instantiate a Field on your class as shown in previous examples.

If you need to customise the behaviour, you can use the field factory inside the dataclasses module.

The parameters to field() are:

default: If provided, this will be the default value for this field. This is needed because the field call itself replaces the normal position of the default value. default_factory: A 0-argument callable that will be called when a default value is needed for this field. init: Included as a parameter to the generated init method. repr: Included in the string returned by the generated repr method. compare: Included in the generated equality and comparison methods (eq, gt, et al.). hash: Included in the generated hash method. There is also another argument, metadata which is not in use yet.

Similar to keyword arguments, fields with default values must be declared last.

Demonstrating the default factory argument,

from dataclasses import dataclass, field
import sys


def get_argv():
    return sys.argv[0]


@dataclass
class SimpleDataObject(object):
  field_a: str
  field_b: str = field(default_factory=get_argv)

example = SimpleDataObject(field_a = 'a')
print(example)  # python3.7 dataclass_4.py test, gives: SimpleDataObject(field_a='a', field_b='dataclass_4.py')

Post-Init İşlemi

Öncesinde oluşturulan init sonrasında işleyen post_init yordamını bildirebilirsiniz.

from dataclasses import dataclass, field
import sys


def get_argv():
    return sys.argv[0]


@dataclass
class SimpleDataObject(object): 
  field_a: str
  field_b: str = field(default_factory=get_argv)

  def __post_init__(self):
      self.field_b = self.field_b.upper()

example = SimpleDataObject(field_a = 'a')
print(example)  # Now SimpleDataObject(field_a='a', field_b='dataclass_4.py')

Data Classes

Sınıfların Kalıtımı

|Kalıtım beklediğiniz gibi çalışır. (Temel ve Miras alınan) sınıf tanımları için sınıfları -dataclass- veri sınıfına sarmanız gerekir.

from dataclasses import dataclass

@dataclass
class SimpleBaseObject(object):
    field_0: str

@dataclass
class SimpleDataObject(SimpleBaseObject):
  field_a: str
  field_b: str

example = SimpleBaseObject('c')
print(example) # Gives : SimpleBaseObject(field_0='c')
SimpleBaseObject(field_0=’c’)

Try it online!

Mevcut bir alandan sonra mevcut olmayan bir alan bildiremeyeceğiniz için, mevcut(field 0) ve mevcut olmayan alanları(field a, field b), temel ve alt sınıflar arasında dağıtımazsınız.

from dataclasses import dataclass

@dataclass
class Point:
    x: float
    y: float
    z: float = 0.0

p = Point(1.5, 2.5)
print(p)
Point(x=1.5, y=2.5, z=0.0)

Try it online!



Son Değişim: 18 Şubat 2019

Paylaş:



En Yeni İçerikler

İlgili İçerikler