Я виявив, що обидві наступні роботи:
class Foo():
def a(self):
print "hello"
class Foo(object):
def a(self):
print "hello"
Чи повинні всі класи Python поширювати об’єкт? Чи є потенційні проблеми з нерозширюваним об'єктом?
Я виявив, що обидві наступні роботи:
class Foo():
def a(self):
print "hello"
class Foo(object):
def a(self):
print "hello"
Чи повинні всі класи Python поширювати об’єкт? Чи є потенційні проблеми з нерозширюваним об'єктом?
Відповіді:
У Python 2 не спадкування від objectстворить клас старого стилю, який, крім інших ефектів, призводить typeдо різних результатів:
>>> class Foo: pass
...
>>> type(Foo())
<type 'instance'>
vs.
>>> class Bar(object): pass
...
>>> type(Bar())
<class '__main__.Bar'>
Також правила багаторазового успадкування різні за способами, які я навіть не намагаюся тут узагальнити. Вся хороша документація, яку я бачив про MI, описує класи нового стилю.
Нарешті, класи в старому стилі зникли в Python 3, і спадкування від objectстало неявним. Отже, завжди віддайте перевагу новим класам стилів, якщо вам не потрібно відсталий співвіт із старим програмним забезпеченням.
У Python 3 заняття поширюються objectнеявно, незалежно від того, говорите ви самі це чи ні.
У Python 2 є класи старого та нового стилю . Щоб сигналізувати класу нового стилю, вам слід явно успадкувати від object. Якщо ні, використовується реалізація старого стилю.
Ви, як правило, хочете клас нового стилю. Спадковуйте від objectявного. Зауважте, що це стосується і коду Python 3, який має бути сумісним з Python 2.
У python 3 ви можете створити клас трьома різними способами, і всередині вони рівні (див. Приклади). Не має значення, як ви створюєте клас, усі класи в python 3 успадковуються від спеціального класу, який називається об'єктом . Клас об'єкт є фундаментальним класом в Python і надає багато функціональних можливості, як методи подвійного підкреслення, дескриптори, супер метод (метод), властивість () і т.д.
Приклад 1.
class MyClass:
pass
Приклад 2.
class MyClass():
pass
Приклад 3.
class MyClass(object):
pass
objectце посилання на вбудований object. Якщо ми маємо врахувати, що будь-який вбудований ідентифікатор CPython можна замінити, ми ледве можемо зробити певне твердження щодо моделі даних. Чи можна серйозно стверджувати, що strне завжди приймається рядок як аргумент, тому що можна призначити builtins.str = None?
Так, всі класи Python повинні поширювати (а точніше підклас, це Python тут) об'єктом. Хоча зазвичай ніяких серйозних проблем не виникне, в деяких випадках (як і з кількома деревами спадкування) це буде важливо. Це також забезпечує кращу сумісність з Python 3.
Як охоплені інші відповіді, успадкування Python 3 від об'єкта неявне. Але вони не вказують, що ви повинні робити і що таке умовність.
Всі приклади документації Python 3 використовують наступний стиль, який є конвенцією, тому я пропоную вам дотримуватися цього для будь-якого майбутнього коду в Python 3.
class Foo:
pass
Джерело: https://docs.python.org/3/tutorial/classes.html#class-objects
Приклад цитати:
Об'єкти класу підтримують два види операцій: посилання на атрибути та інстанції.
Посилання атрибутів використовують стандартний синтаксис, який використовується для всіх посилань на атрибути в Python: obj.name. Дійсні імена атрибутів - це всі імена, які були в просторі імен класу під час створення об’єкта класу. Отже, якщо визначення класу виглядало так:
class MyClass: """A simple example class""" i = 12345 def f(self): return 'hello world'
Ще одна цитата:
Взагалі, змінні екземплярів призначені для даних, унікальних для кожного екземпляра, а змінні класу - для атрибутів і методів, якими поділяються всі екземпляри класу:
class Dog: kind = 'canine' # class variable shared by all instances def __init__(self, name): self.name = name # instance variable unique to each instance
у python3 немає різниці, але в python2 нерозширення objectдає класи старого стилю; ви хочете використовувати клас нового стилю над класом старого стилю.
class Foo():іclass Foo:? Як я зауважую, обидві працюють у Python 3.