Tôi đang cố gắng thiết lập một lớp con pd.DataFrame
có hai đối số bắt buộc khi khởi tạo ( group
và timestamp_col
). Tôi muốn chạy xác thực trên các đối số đó group
và timestamp_col
vì vậy tôi có một phương thức setter cho từng thuộc tính. Tất cả điều này hoạt động cho đến khi tôi cố gắng để set_index()
có được TypeError: 'NoneType' object is not iterable
. Dường như không có đối số nào được truyền cho hàm setter của tôi trong test_set_index
và test_assignment_with_indexed_obj
. Nếu tôi thêm if g == None: return
vào hàm setter của mình, tôi có thể vượt qua các trường hợp thử nghiệm nhưng không nghĩ đó là giải pháp phù hợp.
Làm thế nào tôi nên thực hiện xác nhận thuộc tính cho các đối số cần thiết này?
Dưới đây là lớp học của tôi:
import pandas as pd
import numpy as np
class HistDollarGains(pd.DataFrame):
@property
def _constructor(self):
return HistDollarGains._internal_ctor
_metadata = ["group", "timestamp_col", "_group", "_timestamp_col"]
@classmethod
def _internal_ctor(cls, *args, **kwargs):
kwargs["group"] = None
kwargs["timestamp_col"] = None
return cls(*args, **kwargs)
def __init__(
self,
data,
group,
timestamp_col,
index=None,
columns=None,
dtype=None,
copy=True,
):
super(HistDollarGains, self).__init__(
data=data, index=index, columns=columns, dtype=dtype, copy=copy
)
self.group = group
self.timestamp_col = timestamp_col
@property
def group(self):
return self._group
@group.setter
def group(self, g):
if g == None:
return
if isinstance(g, str):
group_list = [g]
else:
group_list = g
if not set(group_list).issubset(self.columns):
raise ValueError("Data does not contain " + '[' + ', '.join(group_list) + ']')
self._group = group_list
@property
def timestamp_col(self):
return self._timestamp_col
@timestamp_col.setter
def timestamp_col(self, t):
if t == None:
return
if not t in self.columns:
raise ValueError("Data does not contain " + '[' + t + ']')
self._timestamp_col = t
Dưới đây là các trường hợp thử nghiệm của tôi:
import pytest
import pandas as pd
import numpy as np
from myclass import *
@pytest.fixture(scope="module")
def sample():
samp = pd.DataFrame(
[
{"timestamp": "2020-01-01", "group": "a", "dollar_gains": 100},
{"timestamp": "2020-01-01", "group": "b", "dollar_gains": 100},
{"timestamp": "2020-01-01", "group": "c", "dollar_gains": 110},
{"timestamp": "2020-01-01", "group": "a", "dollar_gains": 110},
{"timestamp": "2020-01-01", "group": "b", "dollar_gains": 90},
{"timestamp": "2020-01-01", "group": "d", "dollar_gains": 100},
]
)
return samp
@pytest.fixture(scope="module")
def sample_obj(sample):
return HistDollarGains(sample, "group", "timestamp")
def test_constructor_without_args(sample):
with pytest.raises(TypeError):
HistDollarGains(sample)
def test_constructor_with_string_group(sample):
hist_dg = HistDollarGains(sample, "group", "timestamp")
assert hist_dg.group == ["group"]
assert hist_dg.timestamp_col == "timestamp"
def test_constructor_with_list_group(sample):
hist_dg = HistDollarGains(sample, ["group", "timestamp"], "timestamp")
def test_constructor_with_invalid_group(sample):
with pytest.raises(ValueError):
HistDollarGains(sample, "invalid_group", np.random.choice(sample.columns))
def test_constructor_with_invalid_timestamp(sample):
with pytest.raises(ValueError):
HistDollarGains(sample, np.random.choice(sample.columns), "invalid_timestamp")
def test_assignment_with_indexed_obj(sample_obj):
b = sample_obj.set_index(sample_obj.group + [sample_obj.timestamp_col])
def test_set_index(sample_obj):
# print(isinstance(a, pd.DataFrame))
assert sample_obj.set_index(sample_obj.group + [sample_obj.timestamp_col]).index.names == ['group', 'timestamp']
None
là một giá trị không hợp lệ, đó là lý do tại sao tôi không thích câu lệnh if. Nhưng thêm rằng Không làm cho nó vượt qua các bài kiểm tra. Tôi đang tìm cách khắc phục vấn đề này mà không cần câu lệnh if if.
ValueError
. Vấn đề là tìm ra cái gì đang cố gắng đặt group
thuộc tính None
ở vị trí đầu tiên.
None
là một giá trị không hợp lệ chogroup
tài sản, bạn không nên tăngValueError
?