Giter VIP home page Giter VIP logo

Comments (6)

smartass101 avatar smartass101 commented on August 20, 2024 1

I see two options. A common approach is to use a so called instance factory. It would go something like this:

class B(object):

    def __init__(self, name):
        self.name = name


def B_factory(a):
    if isinstance(a, str):
        return B(a)
    elif isinstance(a, B):
        return a
    else:
        raise TypeError('Unknown name argument')


def test_B_factory():
    a = B_factory('foo')
    b = B_factory(a)
    assert isinstance(a, B)
    assert a is b
    assert a.name is b.name

If you insisted on using just one class and not an intermediate factory function, then it is possible, but a but more convoluted:

class A(object):                # necessary for new-style class in PY2

    def __new__(cls, name):  # actual instance creation
        if isinstance(name, str):  # note PY2 incompatibility
            return super(A, cls).__new__(cls)  # calls object(), will call __init__
        elif isinstance(name, cls):
            return name  # would call __init__ again, need short-circuit in REF1
        else:
            raise TypeError('Unknown name argument')

    def __init__(self, name):  # initializes an instance
        if hasattr(self, 'name'):
            return              # already initialized REF1
        self.name = name


def test_A():
    a = A('foo')
    b = A(a)
    assert a is b
    assert a.name is b.name

I'm not sure whether you plan to support both PY2 and PY3.

from pleque.

smartass101 avatar smartass101 commented on August 20, 2024 1

numpy.array is a factory/conversion/casting function, not a class. The returned class is numpy.ndarray.

Also, I would suggest using something like eq.coordinates() instead of Coordinates(eq). Not a big difference, but might be easier to grasp in terms of OOP.

from pleque.

coobas avatar coobas commented on August 20, 2024

The solution by @smartass101 is good (I'd pick the first one). The main question is why you really need this kind of magic. My answer to this question is that most likely you don't---it's better to solve it upstream (i.e. where you call b = A(a). All this factory / __new__ magic is cool but generally makes the code less readable (which counts a lot).

Btw, do you want copy

a = A('foo')
b = A(a)
assert b == A(a) and b is not A  # b is a copy of a

or identity?

a = A('foo')
b = A(a)
assert b is A(a)  # b is identical to a

from pleque.

coobas avatar coobas commented on August 20, 2024

The third solution via @classmethod (seems to me more readable):

class A:

    def __init__(self, name):
        self.name = name

    @classmethod
    def maybe_create_new_instance(cls, name_or_instance):
        if isinstance(name_or_instance, cls):
            return name_or_instance
        return cls(name_or_instance)


a = A('foo')
assert a is A.maybe_create_new_instance(a)  # b is identical to a
assert a is not A.maybe_create_new_instance('foo')  # creates a new instance

from pleque.

kripnerl avatar kripnerl commented on August 20, 2024

I am speaking about class pleque.core.Coordinate, some showcase of usage is in test.coordinates_test.py:

from pleque.core import Coordinates
from test.testing_utils import load_testing_equilibrium

eq = load_testing_equilibrium()

# 2d coordinates:
coord = Coordinates(eq, 1, 2)
coord = Coordinates(eq, R=1, Z=2)
coord = Coordinates(eq, [1, 2, 3, 4], [3, 5, 6, 2])
coord = Coordinates(eq, ([1, 3], [3, 5], [5, 3]))
coord = Coordinates(eq, np.array(([1, 3], [3, 5], [5, 3])), coord_type=['Z', 'R'])
coord = Coordinates(eq, R=[1, 2, 3, 4], Z=[3, 5, 6, 2])
coord = Coordinates(eq, Z=[3, 5, 6, 2], R=[1, 2, 3, 4])

# 1d coordinates(psi_n):
coord = Coordinates(eq, 0.5)
coord = Coordinates(eq, psi_n=0.5)
coord = Coordinates(eq, np.linspace(0, 1, 6), coord_type='rho')
coord = Coordinates(eq, psi=[0.4, 0.35, 0.3, 0.2, 0.15])
coord = Coordinates(eq, rho=[0, 0.2, 0.4, 0.6, 0.8, 1])
coord = Coordinates(eq, np.linspace(0, 1, 6), coord_type=('rho',))

what I want to be possible is this:

# what I want:
new_coord = Coordinates(coord)
# not implemented yet
assert all(new_coord == coord)
# probably...
assert new_coord is not coord

I treat Coordinates as immutable (don't say it is) but it could change in the future (and most probably will). However, I suppose it would behave similarly as numpy array. However, at the moment, it can be either copy either identity (since copy function is not implemented yet).

Numpy behaviour:

a = np.linspace(0,10,10)
b = np.array(a)

assert all(a == b)
assert a is not b

from pleque.

kripnerl avatar kripnerl commented on August 20, 2024

Implemented as eq.coordinates() in this commit 472dcf5

from pleque.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.