Как получить все поля, методы экземпляра класса и их значения?
Считать все поля экземпляра класса
Есть класс с множеством полей (около 30) public class MyClass < private string p1 private.
Как получить значения статического поля класса с помощью рефлексии?
Есть библиотека классов в ней некоторый класс А. у этого класса есть статическое поле — его ID.
Как можно изменить атрибут экземпляра одного класса при добавлении/изменении экземпляра другого класса
Мне нужно, чтобы при создании города/деревни уже существующей области (т.е. уже создана область с.

Как получить доступ к полю экземпляра класса?
public class Combinations < public static int k = 3; //задаёт размер массива.

Как создать атрибут экземпляра класса в методе экземпляра класса?
Здравствуйте. Подскажите, как в javascript создать новый атрибут экземпляра класса в методе.
![]()
![]()
35346 / 19946 / 4179
Регистрация: 12.02.2012
Сообщений: 33,093
Записей в блоге: 13

Сообщение было отмечено VordyV как решение
Решение
1 2 3 4 5 6 7 8 9
class i: line_1 = 1 line_2 = 2 def __init__(self, arg): self.arg = arg print(i.__dict__)
Python: статические методы, методы класса и экземпляра класса
Согласно модели данных Python, язык предлагает три вида методов: статические, класса и экземпляра класса. Давайте посмотрим, что же происходит за кулисами каждого из видов методов. Понимание принципов их работы поможет в создании красивого и эффективного кода. Начнём с самого простого примера, в котором демонстрируются все три вида методов.
class ToyClass:
def instancemethod(self):
return 'instance method called', self
@classmethod
def classmethod(cls):
return 'class method called', cls @staticmethod
def staticmethod():
return 'static method called'
Методы экземпляра класса
Это наиболее часто используемый вид методов. Методы экземпляра класса принимают объект класса как первый аргумент, который принято называть self и который указывает на сам экземпляр. Количество параметров метода не ограничено.
Используя параметр self , мы можем менять состояние объекта и обращаться к другим его методам и параметрам. К тому же, используя атрибут self.__class__ , мы получаем доступ к атрибутам класса и возможности менять состояние самого класса. То есть методы экземпляров класса позволяют менять как состояние определённого объекта, так и класса.
Встроенный пример метода экземпляра — str.upper() :
>>> "welcome".upper() # 'WELCOME'
Методы класса
Методы класса принимают класс в качестве параметра, который принято обозначать как cls . Он указывает на класс ToyClass, а не на объект этого класса. При декларации методов этого вида используется декоратор classmethod .
Методы класса привязаны к самому классу, а не его экземпляру. Они могут менять состояние класса, что отразится на всех объектах этого класса, но не могут менять конкретный объект.
Встроенный пример метода класса — dict.fromkeys() — возвращает новый словарь с переданными элементами в качестве ключей.
dict.fromkeys('AEIOU') #
Статические методы
Статические методы декларируются при помощи декоратора staticmethod . Им не нужен определённый первый аргумент (ни self , ни cls ).
Их можно воспринимать как методы, которые “не знают, к какому классу относятся”.
Таким образом, статические методы прикреплены к классу лишь для удобства и не могут менять состояние ни класса, ни его экземпляра.
С теорией достаточно. Давайте разберёмся с работой методов, создав объект нашего класса и вызвав поочерёдно каждый из методов: instancemethod, classmethod and staticmethod.
>>> obj = ToyClass()
>>> obj.instancemethod()
('instance method called', ToyClass instance at 0x10f47e7a0>)>>> ToyClass.instancemethod(obj)
('instance method called', ToyClass instance at 0x10f47e7a0>)
Пример выше подтверждает то, что метод instancemethod имеет доступ к объекту класса ToyClass через аргумент self . Кстати, вызов функции obj.instancemethod() используется лишь для удобства, то есть можно использовать и ToyClass.instancemethod(obj) .
Теперь давайте вызовем метод класса:
>>> obj.classmethod()
('class method called', )
Мы видим, что метод класса classmethod() имеет доступ к самому классу ToyClass, но не к его конкретному экземпляру объекта. Запомните, в Python всё является объектом. Класс тоже объект, который мы можем передать функции в качестве аргумента.
Заметьте, что self и cls — не обязательные названия и эти параметры можно называть иначе.
def instancemethod(self, . )
def classmethod(cls, . )-------то же самое, что и----------def instancemethod(my_object, . )
def classmethod(my_class, . )
Это лишь общепринятые обозначения, которым следуют все. Тем не менее они должны находиться первыми в списке параметров.
Вызовем статический метод:
>>> obj.staticmethod()
static method called
Да, это может вас удивить, но статические методы можно вызывать через объект класса. Вызов через точку нужен лишь для удобства. На самом же деле в случае статического метода никакие аргументы ( self или cls ) методу не передаются.
То есть статические методы не могут получить доступ к параметрам класса или объекта. Они работают только с теми данными, которые им передаются в качестве аргументов.
Теперь давайте вызовем те же самые методы, но на самом классе.
>>> ToyClass.classmethod()
('class method called', )>>> ToyClass.staticmethod()
'static method called'>>> ToyClass.instancemethod()
TypeError: unbound method instancemethod()
must be called with ToyClass instance as
first argument (got nothing instead)
Метод класса и статический метод работают, как нужно. Однако вызов метода экземпляра класса выдаёт TypeError, так как метод не может получить на вход экземпляр класса.
Теперь, когда вы знаете разницу между тремя видами методов, давайте рассмотрим реальный пример для понимания того, когда и какой метод стоит использовать. Пример взят отсюда.
from datetime import dateclass Person:
def __init__(self, name, age):
self.name = name
self.age = age@classmethod
def from_birth_year(cls, name, year):
return cls(name, date.today().year - year)@staticmethod
def is_adult(age):
return age > 18person1 = Person('Sarah', 25)
person2 = Person.from_birth_year('Roark', 1994)>>> person1.name, person1.age
Sarah 25>>> person2.name, person2.age
Roark 24>>> Person.is_adult(25)
True
Когда использовать каждый из методов?
Выбор того, какой из методов использовать, может показаться достаточно сложным. Тем не менее с опытом этот выбор делать гораздо проще.
Чаще всего метод класса используется тогда, когда нужен генерирующий метод, возвращающий объект класса. Как видим, метод класса from_birth_year используется для создания объекта класса Person по году рождения, а не возрасту.
Статические методы в основном используются как вспомогательные функции и работают с данными, которые им передаются.
Запомнить
- Методы экземпляра класса получают доступ к объекту класса через параметр self и к классу через self.__class__ .
- Методы класса не могут получить доступ к определённому объекту класса, но имеют доступ к самому классу через cls .
- Статические методы работают как обычные функции, но принадлежат области имён класса. Они не имеют доступа ни к самому классу, ни к его экземплярам.
- Даже если вы программируете только ради интереса, изучение ООП в Python поможет писать код так, чтобы в дальнейшем было легче искать ошибки и использовать его повторно.
Получение всех атрибутов объекта в Python
Одной из распространенных проблем, с которой сталкиваются начинающие разработчики на Python, является необходимость получить все атрибуты (методы, поля и т.д.) объекта. Рассмотрим следующий пример:
class MyClass: def __init__(self): self.a = 1 self.b = 2 def my_method(self): pass
Здесь у нас есть класс MyClass с атрибутами a и b , а также метод my_method . Как мы можем получить список всех этих атрибутов?
В Python есть несколько способов решить эту задачу. Один из них — использование функции vars() . Однако эта функция работает только с объектами, у которых есть __dict__ , что не всегда является правдой (например, это не верно для списка, словаря и т.д.).
my_obj = MyClass() print(vars(my_obj)) # выведет:
Как видите, функция vars() не выводит методы класса. Кроме того, она не работает с встроенными типами, такими как списки или словари.
Более универсальным способом получения всех атрибутов объекта является использование функции dir() . Она возвращает список всех атрибутов объекта, включая методы и встроенные атрибуты.
print(dir(my_obj))
Однако стоит отметить, что dir() также возвращает встроенные атрибуты и методы, что может быть не всегда удобно. Для фильтрации результатов можно использовать различные подходы, например, исключать атрибуты, начинающиеся с двух нижних подчеркиваний.
В заключение, можно сказать, что в Python есть несколько способов получить все атрибуты объекта. Выбор конкретного метода зависит от конкретных требований и обстоятельств.
Объектно-ориентированное программирование¶

Питон является развитым объектно-ориентированным языком. Всё, с чем он работает, является объектами — целые числа, строки, словари, функции и т.д. Каждый объект принадлежит определённому типу (или классу, что одно и то же). Класс тоже является объектом. Классы наследуют друг от друга. Класс object является корнем дерева классов — каждый класс наследует от него прямо или через какие-то промежуточные классы.
object,type(object)
(object, type)
Функция dir возвращает список атрибутов класса.
dir(object)
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
Атрибуты, имена которых начинаются и кончаются двойным подчерком, используются интерпретатором для особых целей. Например, атрибут __doc__ содержит док-строку.
object.__doc__
'The most base type'
help(object)
Help on class object in module builtins: class object | The most base type
Ниже мы рассмотрим цели некоторых других специальных атрибутов.
Вот простейший класс. Поскольку не указано, от чего он наследует, он наследует от object .
class A: pass
A,type(A)
(__main__.A, type)
Создать объект какого-то класса можно, вызвав имя класса как функцию (возможно, с какими-нибудь аргументами). Мы уже это видели: имена классов int , str , list и т.д. создают объекты этих классов.
o=A() o,type(o)
(, __main__.A)
Узнать, какому классу принадлежит объект, можно при помощи функции type или атрибута __class__ .
type(o),o.__class__
(__main__.A, __main__.A)
У только что созданного объекта o нет атрибутов. Их можно создавать (и удалять) налету.
o.x=1 o.y=2 o.x,o.y
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) in () ----> 1 o.z AttributeError: 'A' object has no attribute 'z'
del o.y o.y
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) in () 1 del o.y ----> 2 o.y AttributeError: 'A' object has no attribute 'y'
Такой объект похож на словарь, ключами которого являются имена атрибутов: можно узнать значение атрибута, изменить его, добавить новый или удалить старый. Это и неудивительно: для реализации атрибутов объекта используется именно словарь.
o.__dict__
Класс вводит пространство имён. В описании класса мы определяем его атрибуты (атрибуты, являющиеся функциями, называются методами). Потом эти атрибуты можно использовать как Class.attribute . Принято, чтобы имена классов начинались с заглавной буквы.
Вот более полный пример класса. В нём есть док-строка, метод f , статический атрибут x (атрибут класса, а не конкретного объекта) и статический метод getx (опять же принадлежащий классу, а не конкретному объекту).
class S: 'Простой класс' x=1 def f(self): print(self) @staticmethod def getx(): return S.x
Заклинание тёмной магии, начинающееся с @ , называется декоратором. Запись
@dec def fun(x): .
def fun(x): . fun=dec(fun)
То есть dec — это функция, параметр которой — функция, и он возвращает эту функцию, преобразованную некоторым образом. Мы не будем обсуждать, как самим сочинять такие заклинания — за этим обращайтесь в Дурмстранг.
Функция dir возвращает список атрибутов класса. Чтобы не смотреть снова на атрибуты, унаследованные от object , мы их вычтем.
set(dir(S))-set(dir(object))
dict(S.__dict__)
, '__doc__': 'Простой класс', '__module__': '__main__', '__weakref__': , 'f': , 'getx': , 'x': 1>
S.x=2 S.x
S.f,S.getx
S.getx()
Теперь создадим объект этого класса.
o=S() o,type(o)
(, __main__.S)
Метод класса можно вызвать и через объект.
o.getx()
Следующее присваивание создаёт атрибут объекта o с именем x . Когда мы запрашиваем o.x , атрибут x ищется сначала в объекте o , а если он там не найден — в его классе. В данном случае он найдётся в объекте o . На атрибут класса S.x это присваивание не влияет.
o.x=5 o.x,S.x
Как мы уже обсуждали, можно вызвать метод класса S.f с каким-нибудь аргументом, например, o .
Следующий вызов означает в точности то же самое. Интерпретатор питон фактически преобразует его в предыдущий.
То есть текущий объект передаётся методу в качестве первого аргумента. Этот первый аргумент любого метода принято называть self . В принципе, Вы можете назвать его как угодно, но это затруднит понимание Вашего класса читателями, воспитанными в этой традиции.
Отличие метода класса ( @staticmethod ) от метода объекта состоит в том, что такое автоматическое вставление первого аргумента не производится.
o.f — это связанный метод: S.f связанный с объектом o .
Док-строка доступна как атрибут __doc__ и используется функцией help .
S.__doc__
'Простой класс'
help(S)
Help on class S in module __main__: class S(builtins.object) | Простой класс | | Methods defined here: | | f(self) | | ---------------------------------------------------------------------- | Static methods defined here: | | getx() | | ---------------------------------------------------------------------- | Data descriptors defined here: | | __dict__ | dictionary for instance variables (if defined) | | __weakref__ | list of weak references to the object (if defined) | | ---------------------------------------------------------------------- | Data and other attributes defined here: | | x = 2
Классу можно добавить новый атрибут налету (равно как и удалить имеющийся).
S.y=2 S.y
Можно добавить и атрибут, являющийся функцией, т.е. метод. Сначала опишем (вне тела класса!) какую-нибудь функцию, а потом добавим её к классу в качестве нового метода.
def g(self): print(self.y) S.g=g o.g()
Менять класс налету таким образом — плохая идея. Когда в каком-то месте программы Вы видете, что используется какой-то объект некоторого класса, первое, что Вы сделаете — это посмотрите определение этого класса. И если текущее его состояние отлично от его определения, это сильно затрудняет понимание программы.
Класс S , который мы рассмотрели в качестве примера — отнюдь не пример для подражания. В нормальном объектно-ориентированном подходе объект класса должен создаваться в допустимом (пригодном к использованию) состоянии, со всеми необходимыми атрибутами. В других языках за это твечает конструктор. В питоне аналогичную роль играет метод инициализации __init__ . Вот пример такого класса.
class C: def __init__(self,x): self.x=x def getx(self): return self.x def setx(self,x): self.x=x
Теперь для создания объекта мы должны вызвать C с одним аргументом x (первый аргумент метода __init__ , self , это свежесозданный объект, в котором ещё ничего нет и который надо инициализировать).
o=C(1) o.getx()
o.setx(2) o.getx()
Этот класс — тоже не пример для подражания. В некоторых объектно-ориентированных языках считается некошерным напрямую читать и писать атрибуты; считается, что вся работа должна производиться через вызов методов. В питоне этот предрассудок не разделяют. Так что писать методы типа getx и setx абсолютно излишне. Они не добавляют никакой полезной функциональности — всё можно сделать, просто используя атрибут x .
Любой объектно-ориентированный язык, заслуживающий такого названия, поддерживает наследование. Класс C2 наследует от C . Его объекты являются вполне законными для класса C (имеют атрибут x ), но в добавок к этому имеют ещё и атрибут y . Метод __init__ теперь должен иметь 2 параметра x и y (не считая обязательного self ). К методам getx и setx , унаследованным от C , добавляются методы gety и sety .
Чтобы инициализировать атрибут x , который был в родительском классе, мы могли бы, конечно, скопировать код из метода __init__ класса C . В данном случае он столь прост, что это не преступление. Но, вообще говоря, копировать куски кода из одного места в другое категорически не рекомендуется. Допустим, в скопированном куске найден и исправлен баг. А в копии он остался. Поэтому для инициализации нового объекта, рассматриваемого как объект родительского класса C , нам следует вызвать метод __init__ класса C , а после этого довавить инициализацию атрибута y , специфичного для дочернего класса C2 . Первую часть задачи можно выполнить, вызвав C.__init__(self,x) (мы ведь только что написали строчку class , в которой указали, что класс-предок называется C ). Но есть более универсальный метод, не требующий второй раз писать имя родительского класса. Функция super() возвращает текущий объект self , рассматриваемый как объект родительского класса C . Поэтому мы можем написать super().__init__(x) .
Конечно, не только __init__ , но и другие методы дочернего класса могут захотеть вызвать методы родительского класса. Для этого используется либо вызов через имя родительского класса, либо super() .
class C2(C): def __init__(self,x,y): super().__init__(x) self.y=y def gety(self): return self.y def sety(self,y): self.y=y