Code Review Doctor suggests a fix if your code does not follows Python maintainability best practices.
This frees your team to be more agile - they can focus on adding value rather than fighting with old tech debt.
1 | + | class FooBarClass(object): |
A class is inherited from object
by default, so explicitly inheriting from object is redundant. Removing it keeps the code simpler.
- | class FooBarClass(object): |
+ | class FooBarClass: |
2 | + | pass |
1 | + | if isinstance(item, int) or isinstance(item, float): |
isinstance
can take multiple types, so there is no need to call them multiple times for each type.
- | if isinstance(item, int) or isinstance(item, float): |
+ | if isinstance(item, (int, float)): |
2 | + | pass |
1 | + | if isinstance(item, int) or isinstance(item, float): |
isinstance
can take multiple types, so there is no need to call them multiple times for each type.
- | if isinstance(item, int) or isinstance(item, float): |
+ | if isinstance(item, (int, float)): |
2 | + | pass |
1 | + | class FooBarClass(NamedTuple): |
Consider using the dataclass
here instead for simplicity, performance gains, and consistency
- | class FooBarClass(NamedTuple): |
+ | @dataclass(frozen=True) |
+ | class FooBarClass: |
pass |
2 | + | pass |
1 | + | class FooBarClass(Bar): | |
2 | + | def foo(self, bar): | |
3 | + | super(Foo, self).foo(bar) |
It's unnecessary to use arguments when calling super for the parent class.
Read more- | super(Foo, self).foo(bar) |
+ | super().foo(bar) |
1 | + | value = f'some-value' |
f-string is unnecessary here as there are no placeholders in the string.
Read more- | value = f'some-value' |
+ | value = 'some-value' |
1 | + | foo = lambda x: bar(x) |
Avoid unnecessarily wrapping a function in a lambda
Read more- | foo = lambda x: bar(x) |
+ | foo = bar |
1 | + | any([item for item in items]) |
all
and any
can take a generator, so constructing a list first may be unnecessary.
- | any([item for item in items]) |
+ | any(item for item in items) |
1 | + | def foo_bar() -> "FooBarClass": |
Use type identifiers instead of using string type hints.
Read more- | def foo_bar() -> "FooBarClass": | |||
+ | def foo_bar() -> FooBarClass: | |||
Expand 4 lines ... |
2 | + | return FooBarClass() | |
3 | + | ||
4 | + | class FooBarClass: | |
5 | + | pass |
1 | + | def foo_bar() -> Union[int, None]: |
This could be simplified by using typing.Optional
- | def foo_bar() -> Union[int, None]: |
+ | def foo_bar() -> Optional[int]: |
2 | + | # sometimes return int other times None |
1 | + | dict((item, get_value(item)) for item in items) |
Using list and dict comprehension is simpler and computationally quicker than calling list()
and dict()
.
- | dict((item, get_value(item)) for item in items) |
+ | {item: get_value(item) item item in items} |
1 | + | values = list([1, 2, 3]) |
Using list/set/dict literal syntax is simpler and computationally quicker than calling list()
, set()
, or dict()
.
- | values = list([1, 2, 3]) |
+ | values = [1, 2, 3] |
1 | + | def get_name(user): | |
2 | + | return "%s %s" % (user.first_name, user.last_name) |
f-string is easier to read, write, and less computationally expensive than legacy string formatting.
Read more- | return "%s %s" % (user.first_name, user.last_name) |
+ | return f'{user.first_name} {user.last_name}' |
1 | + | from typing import Optional | |
2 | + | ||
3 | + | def foo_bar(value: Optional[str] = None): | |
4 | + | if value: |
Checking Optional variables against None
would be more explicit.
- | if value: |
+ | if value is not None: |
5 | + | ... |
1 | + | with open('some/path.json') as f: | |
2 | + | content = json.loads(f.read()) |
json.load(f)
simplifies reading JSON from disk.
- | content = json.loads(f.read()) |
+ | content = json.load(f) |
1 | + | with open('some/path.json', 'w') as f: | |
2 | + | f.write(json.dumps({'foo': 'bar'})) |
json.dump(f)
simplifies writing JSON to disk.
- | f.write(json.dumps({'foo': 'bar'})) |
+ | json.dump({'foo': 'bar'}, f) |
Are you ready to improve your team agility through lower tech debt? Add Code Review Doctor to GitHub.